照例良心题目链接
此题使用f[i][j]表示前i束花放进前j个花瓶的时候的最大值。转移方程如下
f[i][j]=max(f[i][j-1],f[i-1][j-1]+que[i][j])
其中que[i][j]表示第i束花放进第j个花瓶里的情况。有这个转移方程的原因是,每一束花在每一个花瓶里的情况只有两种:放进去了和没放进去。第一种f[i][j-1]就是没放进去,第二种
f[i-1][j-1]+que[i][j]就是放进去了的情况
特殊的,当i>=j时第一种情况不能成立
路径保存死活没想出来,最后参考题解发现了一个递归输出——于是就可耻的抄了下来。
代码如下
#include<cstdio> #include<cctype> #include<cstdlib> #include<cstring> inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int que[1000][1000]; int f[1000][1000]; int last[1000][1000]; void print(int a,int b){ if(!a||!b)return; if(last[a][b]){ print(a-1,b-1); printf("%d ",b); } else print(a,b-1); return; } int main(){ //memset(f,0xaf,sizeof(f)); int n=read(),m=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) que[i][j]=read(); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(f[i][j-1]<f[i-1][j-1]+que[i][j]||i>=j){ f[i][j]=f[i-1][j-1]+que[i][j]; last[i][j]=1; } else f[i][j]=f[i][j-1]; } } printf("%d\n",f[n][m]); print(n,m); return 0; }