第一个思路:无论如何每行都要选一个,因此初始化num为1。
https://www.luogu.com.cn/record/66958296
第二个思路:初始化num为0,且数组0标记为-INF,因此取到最大值。
https://www.luogu.com.cn/record/66959725
结果都不对。
#include<iostream>
#include<cstdio>
#include<stack>
const int maxn=500,maxh=(1<<30)-1;
using namespace std;
int N,M,a[maxn][maxn],f[maxn],fl[maxn][maxn],ans=0;
stack<int>st;
int main(){
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
scanf("%d",&a[i][j]);
}
}
// f[0]=-maxh;
//i-1,num upd i,j
for(int i=1;i<=N;i++){//think of the -
for(int j=M;j;j--){//think of the .
int num=1;
for(int k=1;k<j;k++)//choose from last
if(f[num]<f[k]) num=k;
fl[i][j]=num;
// printf("%d %d to %d %d\n",i-1,num,i,j);
// printf("f[%d]+a[%d][%d]updf[%d]\n",num,i,j,j);
f[j]=a[i][j]+f[num];
}
}
f[0]=-maxh;
for(int i=1;i<=M;i++){
if(f[ans]<f[i]) ans=i;
// printf("%d\n",f[i]);
}
st.push(ans);
printf("%d\n",f[ans]);
for(int i=N;i>1;i--){
ans=fl[i][ans];//in fact record i+1.from(i.at)
st.push(ans);
}
while(!st.empty()){printf("%d ",st.top());st.pop();}
printf("\n");
return 0;
}
#include<cstdio>
#include<stack>
const int maxn=500,maxh=(1<<30)-1;
using namespace std;
int N,M,a[maxn][maxn],f[maxn],fl[maxn][maxn],ans=0;
stack<int>st;
int main(){
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
scanf("%d",&a[i][j]);
}
}
f[0]=-maxh;
//i-1,num upd i,j
for(int i=1;i<=N;i++){//think of the -
for(int j=M;j;j--){//think of the .
int num=0;
for(int k=1;k<j;k++)//choose from last
if(f[num]<f[k]) num=k;
fl[i][j]=num;
// printf("%d %d to %d %d\n",i-1,num,i,j);
// printf("f[%d]+a[%d][%d]updf[%d]\n",num,i,j,j);
f[j]=a[i][j]+f[num];
}
}
f[0]=-maxh;
for(int i=1;i<=M;i++){
if(f[ans]<f[i]) ans=i;
// printf("%d\n",f[i]);
}
st.push(ans);
printf("%d\n",f[ans]);
for(int i=N;i>1;i--){
ans=fl[i][ans];//in fact record i+1.from(i.at)
st.push(ans);
}
while(!st.empty()){printf("%d ",st.top());st.pop();}
printf("\n");
return 0;
}