有n个高度都为h的树(b[i]) ,树上的一些高度处有若干果实(比如b[i][h]==3) ,猫从任意的树顶部出发,可以
1.跳到任意其他的树上,高度将下降D
2.向下滑1个单位
问最多获得多少果实?
明显的dp
暴力程序 O(n^3)
#include <iostream>
#include <algorithm>
using namespace std ;
const int M=2003,N=5003;
int n,h,D,f[N][M];
int b[N][M];
void solve(){
int i,j,k,ans=0;
for(j=0;j<=h;j++)
for(i=1;i<=n;i++){
f[i][j]=max(f[i][j],f[i][j-1]+b[i][j]);
for(k=1;k<=n;k++){
if(k!=i&&j>=D) f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);
}
}
for(i=1;i<=n;i++) ans=max(ans,f[i][h]);
cout<<ans;
}
signed main(){
int i,x,t;
cin>>n>>h>>D;
for(i=1;i<=n;i++){
cin>>t;
while(t--) cin>>x,b[i][x]++;
}
solve();
}
重点来了,可以去掉 k 的枚举
f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);
k的枚举的目的是 找 f[k][height] 最大,可以维护一下,然后直接用
ht[j] 表示高度j 时 , f[k][j] 的最大值
er高度是也从小到大枚举的,没毛病
O(n^2)
#include <iostream>
#include <algorithm>
using namespace std ;
const int M=2003,N=5003;
int n,h,D,f[N][M],ht[M];
int b[N][M];
void solve(){
int i,j,k,ans=0;
for(j=0;j<=h;j++)
for(i=1;i<=n;i++){
f[i][j]=max(f[i][j],f[i][j-1]+b[i][j]);
// if(k!=i&&j>=D) f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);
if(j>=D) f[i][j]=max(f[i][j],ht[j-D]+b[i][j]);
ht[j]=max(ht[j],f[i][j]);
}
for(i=1;i<=n;i++) ans=max(ans,f[i][h]);
cout<<ans;
}
signed main(){
int i,x,t;
cin>>n>>h>>D;
for(i=1;i<=n;i++){
cin>>t;
while(t--) cin>>x,b[i][x]++;
}
solve();
}