標籤:dp
連結:UVa 10003
題意:給出一根木棍的長度,及木棍上的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 100000int 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 100000int 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;}