洛谷 P1854 花店橱窗布置 题解

[亡魂溺海] 提交于 2019-12-03 17:28:02

洛谷 P1854 花店橱窗布置 题解

 

Analysis

给定一个f*v的矩阵

要求从第一行走到第f行,每行取走一个数,

且该行所取的数必须必上一行所取的数的列数大 , 求所能取走的最大值

注意每一行所取走的数字的列数必须大于等该行的行号

因为必须给前面的花留下足够的花瓶

同理每一行所能取的最大的花瓶号必须小于等于v-(f-该行行数)

由此我们便可以很容易的得出状态转移方程

dp[i][j]=max(dp[i-1][k])+d[i][j](k<j)dp[i][j]=max(dp[i1][k])+d[i][j](k<j)

其中dp[i][j]dp[i][j]表示从第一行走到第i行并取走该行第j个数所能取得的最大值

 

复制代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 #define int long long
 7 #define maxn 100+10
 8 #define INF 9223372036854775807
 9 using namespace std;
10 inline int read() 
11 {
12     int x=0;
13     bool f=1;
14     char c=getchar();
15     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
16     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
17     if(f) return x;
18     return 0-x;
19 }
20 inline void write(int x)
21 {
22     if(x<0){putchar('-');x=-x;}
23     if(x>9)write(x/10);
24     putchar(x%10+'0');
25 }
26 int f,v;
27 int map[maxn][maxn];
28 int dp[maxn][maxn];
29 int path[maxn][maxn];
30 stack<int> s;
31 inline void print(int num,int x)
32 {
33     if(num==0) return;
34     s.push(x);
35     print(num-1,path[num][x]);
36 }
37 signed main()
38 {
39     freopen("flower.in","r",stdin);
40     freopen("flower.out","w",stdout);
41     memset(dp,128,sizeof(dp));
42     f=read();v=read();
43     for(int i=1;i<=f;i++)
44         for(int j=1;j<=v;j++)
45             map[i][j]=read();
46     for(int i=1;i<=v;i++) dp[1][i]=map[1][i];
47     for(int i=2;i<=f;i++)
48         for(int j=i;j<=v-(f-i);j++)
49             for(int k=1;k<j;k++)
50             {
51                 if(dp[i-1][k]+map[i][j]>dp[i][j])
52                 {
53                     dp[i][j]=dp[i-1][k]+map[i][j];
54                     path[i][j]=k;
55                 }
56             }
57     int ans=-INF,fnum=0;
58     for(int i=1;i<=v;i++)
59         if(dp[f][i]>ans)
60         {
61             ans=dp[f][i];
62             fnum=i;
63         }
64     write(ans);
65     printf("\n");
66     print(f,fnum);
67     while(!s.empty())
68     {
69         write(s.top());
70         printf(" ");
71         s.pop();
72     }
73     return 0;
74 }
复制代码

请各位大佬斧正(反正我不认识斧正是什么意思)

Analysis

给定一个f*v的矩阵

要求从第一行走到第f行,每行取走一个数,

且该行所取的数必须必上一行所取的数的列数大 , 求所能取走的最大值

注意每一行所取走的数字的列数必须大于等该行的行号

因为必须给前面的花留下足够的花瓶

同理每一行所能取的最大的花瓶号必须小于等于v-(f-该行行数)

由此我们便可以很容易的得出状态转移方程

dp[i][j]=max(dp[i-1][k])+d[i][j](k<j)dp[i][j]=max(dp[i1][k])+d[i][j](k<j)

其中dp[i][j]dp[i][j]表示从第一行走到第i行并取走该行第j个数所能取得的最大值

 

复制代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 #define int long long
 7 #define maxn 100+10
 8 #define INF 9223372036854775807
 9 using namespace std;
10 inline int read() 
11 {
12     int x=0;
13     bool f=1;
14     char c=getchar();
15     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
16     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
17     if(f) return x;
18     return 0-x;
19 }
20 inline void write(int x)
21 {
22     if(x<0){putchar('-');x=-x;}
23     if(x>9)write(x/10);
24     putchar(x%10+'0');
25 }
26 int f,v;
27 int map[maxn][maxn];
28 int dp[maxn][maxn];
29 int path[maxn][maxn];
30 stack<int> s;
31 inline void print(int num,int x)
32 {
33     if(num==0) return;
34     s.push(x);
35     print(num-1,path[num][x]);
36 }
37 signed main()
38 {
39     freopen("flower.in","r",stdin);
40     freopen("flower.out","w",stdout);
41     memset(dp,128,sizeof(dp));
42     f=read();v=read();
43     for(int i=1;i<=f;i++)
44         for(int j=1;j<=v;j++)
45             map[i][j]=read();
46     for(int i=1;i<=v;i++) dp[1][i]=map[1][i];
47     for(int i=2;i<=f;i++)
48         for(int j=i;j<=v-(f-i);j++)
49             for(int k=1;k<j;k++)
50             {
51                 if(dp[i-1][k]+map[i][j]>dp[i][j])
52                 {
53                     dp[i][j]=dp[i-1][k]+map[i][j];
54                     path[i][j]=k;
55                 }
56             }
57     int ans=-INF,fnum=0;
58     for(int i=1;i<=v;i++)
59         if(dp[f][i]>ans)
60         {
61             ans=dp[f][i];
62             fnum=i;
63         }
64     write(ans);
65     printf("\n");
66     print(f,fnum);
67     while(!s.empty())
68     {
69         write(s.top());
70         printf(" ");
71         s.pop();
72     }
73     return 0;
74 }
复制代码

请各位大佬斧正(反正我不认识斧正是什么意思)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!