【Luogu】P1854花店櫥窗布置(DP)


照例良心題目鏈接

   此題使用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;
}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com