标签:dp
题意:给出一根木棍的长度,及木棍上的n个点,要在这n个点处切断木棍,在切断木棍时木棍有多长就花费多少代价,求将给定的所有点都切断的最小代价
分析:这个是区间dp的题,用dp[i][j]数组表示在区间[i,j]内切割木棍的最小代价,
则状态转移方程为dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+a[j]-a[i]) (i<=k< j)
参考代码:
#include<stdio.h> #include<string.h> #define M 100000 int min(int a,int b) { return a<b?a:b; } int main() { int a[55],n,i,j,l,r,k,m,dp[55][55]; while(scanf("%d",&m)!=EOF){ if(m==0) break; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); a[0]=0; //添加头尾点 a[n+1]=m; for(i=0;i<=n;i++){ dp[i][i+1]=0; for(j=i+2;j<=n+1;j++) dp[i][j]=M; } for(i=1;i<=n+1;i++) //分段 for(l=0;l<=n+1-i;l++){ //r-l=i<=n+1 --> l<=n+1-i r=l+i; for(k=l+1;k<r;k++) dp[l][r]=min(dp[l][r],dp[l][k]+dp[k][r]+a[r]-a[l]); } printf("The minimum cutting is %d.\n",dp[0][n+1]); } return 0; }
#include<stdio.h> #include<string.h> #define M 100000 int a[55],dp[55][55]; int min(int a,int b) { return a<b?a:b; } int my_dp(int l,int r) { int i; if(dp[l][r]!=M) return dp[l][r]; for(i=l+1;i<r;i++) dp[l][r]=min(dp[l][r],my_dp(l,i)+my_dp(i,r)+a[r]-a[l]); return dp[l][r]; } int main() { int i,j,n,m; while(scanf("%d",&m)!=EOF){ if(m==0) break; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); a[0]=0; a[n+1]=m; for(i=0;i<=n;i++){ dp[i][i+1]=0; for(j=i+2;j<=n+1;j++) dp[i][j]=M; } my_dp(0,n+1); printf("The minimum cutting is %d.\n",dp[0][n+1]); } return 0; }
UVa 10003 Cutting Sticks (区间dp),布布扣,bubuko.com
UVa 10003 Cutting Sticks (区间dp)
标签:dp
原文地址:http://blog.csdn.net/acm_code/article/details/38453107