动态规划/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 }

 

posted @ 2012-12-02 17:56  Rinyo  阅读(172)  评论(0编辑  收藏  举报