标签:区间dp
Description
Input
Output
Sample Input
3 2 5 1
Sample Output
11
第一道区间dp,这题设一个数组dp[i][j]表示从i取到j的最小得分。
状态转移方程:dp[i][i+len]=min(dp[i][i+len],dp[i][i+len1]+dp[i+len1+1][i+len]+sum[i+len]-sum[i-1]);这里注意所有的dp[i][i]为0,因为只有一个数的时候不用合并,所以是0。因为题目允许第一次开始取的时候相邻数字能搞交换,所以外面加个循环,同时每次的sum[],dp[i][i+1]都要重新初始化。另外,这题用四边形优化会大大加快速度。
#include<stdio.h> #include<string.h> #define inf 88888888 int min(int a,int b){ return a<b?a:b; } int a[106],dp[106][106],sum[106]; int main() { int n,m,i,j,temp,len,sum1,ans,len1,k; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++){ scanf("%d",&a[i]); } sum1=inf; for(k=1;k<=n-1;k++){ temp=a[k]; a[k]=a[k+1]; a[k+1]=temp; memset(sum,0,sizeof(sum)); memset(dp,inf,sizeof(dp)); for(i=1;i<=n-1;i++){ sum[i]=sum[i-1]+a[i]; dp[i][i+1]=a[i]+a[i+1];dp[i][i]=0; } dp[n][n]=0;sum[n]=sum[n-1]+a[n]; for(len=2;len<=n-1;len++){ for(i=1;i+len<=n;i++){ for(len1=0;len1<len;len1++){ dp[i][i+len]=min(dp[i][i+len],dp[i][i+len1]+dp[i+len1+1][i+len]+sum[i+len]-sum[i-1]); } } } temp=a[k]; a[k]=a[k+1]; a[k+1]=temp; if(dp[1][n]<sum1)sum1=dp[1][n]; } printf("%d\n",sum1); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:区间dp
原文地址:http://blog.csdn.net/kirito_acmer/article/details/46897159