Topic Link: Click to enter
Previously also encountered this type of DP, the feeling is that the state is not good definition and transfer, the original definition of the state is always considered dp[i][j] should be transferred from the dp[i-1][j-1], which will lead to the need to remember the front i-1 step of all states, and then the transfer equation can not be written. For this problem, we define state Dp[i][j] to represent the minimum cost of building I warehouses for the first J restaurants, and then state to dp[i][j]=dp[i-1][k-1]+cost[k][j], meaning: The former i-1 warehouses that have been established are responsible for the former k-1 restaurants, Then the I restaurant is responsible for the first k–j restaurants, of which k<=i<=j; And then it's the subject that needs to be printed every time, and we'll just push back in the final state.
The code is as follows:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace STD;intdp[ -][ -],n,k;inta[222],cost[ -][ -];int ABS(intx) {if(x<0) X=-x;returnx;}intCalintIintj) {intM= (I+J)/2;intsum=0; for(intd=i;d<=j;d++) sum+=ABS(A[d]-a[m]);returnsum;}voidPrintintIintj) {if(i==1) {intD= (I+J)/2;printf("Depot%d at restaurant%d serves restaurants%d to%d\n", i,d,i,j);return; }Else{ for(intd=i;d<=j;d++) {if(dp[i-1][d-1]+cost[d][j]==dp[i][j]) {print (I-1, d1);printf("Depot%d at restaurant%d serves restaurants%d to%d\n", I, (d+j)/2, d,j);return; } } }}intMain () {///freopen ("In.txt", "R", stdin); intCase=0; while(scanf("%d%d", &n,&k)!=eof) {if(n==0&&k==0) Break; for(intI=1; i<=n;i++)scanf("%d", &a[i]);memset(DP,0x3f,sizeof(DP)); for(intI=1; i<=n;i++) for(intj=i;j<=n;j++) cost[i][j]=cal (I,J); for(intI=1; i<=n;i++) dp[1][i]=cost[1][i]; for(intI=2; i<=k;i++) for(intj=i;j<=n;j++) { for(intd=i;d<=j;d++) Dp[i][j]=min (dp[i-1][d-1]+COST[D][J],DP[I][J]); }printf("Chain%d\n", ++case); Print (k,n);printf("total distance sum =%d\n\n", Dp[k][n]); }return 0;}
UVA 662 Fast Food + classic Dynamic Planning