[USACO13NOV]POGO的牛Pogo-Cow
Dp
题解:
1000的数据,Luogu上被n^3水过,500ms+
我能怎么办,我也很绝望啊~
f[i][j]表示第i个从第j个转移过来的最大价值
边界:f[i][i]=c[i]
转移:暴力枚举下一个
——————乱搞分割线——————
(严肃脸)
i是当前,j是上一个,k是下一个
k只能从连续的一段j中转移
或许正解是log维护区间的max?
—————————————————
Code:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
const int N = 1005;
int n,ans,f[N][N];
struct Point{
int p,c;
bool operator < (const Point &other) const { return p < other.p; }
} d[N];
inline void upd(int &a,int b){ a=max(a,b); ans=max(ans,a); }
inline int myabs(int a){ return a>=0 ? a : -a; }
void solve(){
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++){
upd(f[i][i],d[i].c);
for(int k=i+1;k<=n;k++){
int len=myabs(d[k].p-d[i].p);
for(int j=i;j>=1;j--){
if(myabs(d[i].p-d[j].p)>len) break;
upd(f[k][i],f[i][j]+d[k].c);
}
}
}
}
int main(){
freopen("a.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&d[i].p,&d[i].c);
}
sort(d+1,d+1+n);
// for(int i=1;i<=n;i++) printf("%d %d\n",d[i].p,d[i].c);
solve();
reverse(d+1,d+1+n);
solve();
printf("%d\n",ans);
}