洛谷 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[i−1][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 }
请各位大佬斧正(反正我不认识斧正是什么意思)




