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

 

你可能感兴趣的:(动态规划)