动态规划/sgu104 Little shop of flowers
题意
给出n朵花,m个花瓶,第i号花插在第j个花瓶可以得到的权值是w,要求从左向右依次插花,求可以得到的最大权值,并打印插花方案
分析
简单的线性dp,记f[i,j]为从第一号花开始插,插到了第i号花,且第i号花插在第j个花瓶,所能得到的权值之和为多少
显然,f[i,j]=max{f[i-1,k]+w[i,j]} k∈[i-1,j)
这样,问题的一部分求解完了,关键是如何记录答案
开个数组ans[i,j,0..1]。表示第i朵花插在第j个花瓶时,它的前一朵花为ans[i,j,0],且这朵花插在了f[i,j,1]上。
这样,写个递归就可以得到插花方案
Accepted Code
1 /* 2 PROBLEM:sgu104 3 AUTHER:Rinyo 4 MEMO:dp 5 */ 6 7 #include <cstdio> 8 int f[130][130],a[130][130],ans[130][130][3]; 9 int n,m; 10 11 void print(int x,int y) 12 { 13 if(x==1) 14 { 15 printf("%d",y); 16 return; 17 } 18 print(ans[x][y][0],ans[x][y][1]); 19 printf(" %d",y); 20 return; 21 } 22 23 int main() 24 { 25 int INF=-999999999; 26 scanf("%d%d",&n,&m); 27 for (int i=1;i<=n;i++) 28 for (int j=1;j<=m;j++) scanf("%d",&a[i][j]); 29 for (int i=1;i<=n;i++) 30 for (int j=1;j<=m;j++) f[i][j]=INF; 31 f[0][0]=0; 32 for (int i=1;i<=n;i++) 33 for (int j=1;j<=m;j++) 34 { 35 for (int k=i-1;k<j;k++) 36 if (f[i][j]<f[i-1][k]+a[i][j]) 37 { 38 f[i][j]=f[i-1][k]+a[i][j]; 39 ans[i][j][0]=i-1; 40 ans[i][j][1]=k; 41 } 42 } 43 int max=INF; 44 int p; 45 for (int i=1;i<=m;i++) 46 { 47 if (max<f[n][i]) {max=f[n][i];p=i;} 48 } 49 50 printf("%d\n",max); 51 print(n,p); 52 return 0; 53 }