分析
对于一道地道的DP题,首先要解决的是如何记忆化搜索,设置一个状态,这里我们看到有两个参数,f和v,自然就想到了用二维数组来保存状态了。
dp[i][j]
表示在第
i
朵花摆在第
所以状态方程就可以求出来了:
dp[i][j]=max(dp[i−1][k])+a[i][j];(k∈[1,j−1])
code
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int num=0;
char c=' ';
bool flag=true;
for(;c>'9'||c<'0';c=getchar())
if(c=='-')
flag=false;
for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());
return flag ? num : -num;
}
#define maxn 120
#define INF 2e9
int f,v,a[maxn][maxn],dp[maxn][maxn];
int s[maxn][maxn],q[maxn];
int main()
{
f=read();
v=read();
for(int i=1;i<=f;i++)
for(int j=1;j<=v;j++)
{
a[i][j]=read();
dp[i][j]=-INF;
}
for(int i=1;i<=f;i++)
dp[0][i]=0;
for(int i=1;i<=f;i++)
for(int j=i;j<=v;j++)
{
for(int k=i-1;k<=j-1;k++)
{
if(dp[i][j]<dp[i-1][k]+a[i][j])
{
dp[i][j]=dp[i-1][k]+a[i][j];
s[i][j]=k;
}
//找出最大的,然后更新dp数组
}
}
int ans=-INF;
for(int i=1;i<=v;i++)
{
if(dp[f][i]>ans)
{
q[f]=i;
ans=dp[f][i];
}
}//所有的dp数组中找出最大的配置
printf("%d\n",ans);
for(int i=f;s[i][q[i]]!=0;i--)
q[i-1]=s[i][q[i]];
for(int i=1;i<=f-1;i++)
printf("%d ",q[i]);
printf("%d\n",q[f]);
//问sharpland!!不规范输入输出要被卡
return 0;
}