[Contest on 2020.11.28] 精靈
阿新 • • 發佈:2020-11-28
\(\text{Solution}\)
顯然有 \(f[l][r][t][2]\) 的區間 \(\text{DP}\)。
這裡主要是講一下空間優化:
- 發現區間一定包含 \(pos\)(即出發點),所以定義 \(l\) 為離 \(pos\) 距離為 \(l\)(向左延伸),\(r\) 同理(向右延伸),可以將空間除以 \(4\)。
- 考慮一定不會有 \(l>r\) 的情況,我們可以將 \(l<r\) 時裝 \(0\) 狀態,用 \(l>r\) 裝 \(1\) 狀態,好像只能除以 \(2\)。
\(\text{Advance}\)
\(\text{Code}\)
#include <cstdio> #define rep(i,_l,_r) for(signed i=(_l),_end=(_r);i<=_end;++i) int read() { int x=0,f=1; char s; while((s=getchar())>'9'||s<'0') if(s=='-') f=-1; while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar(); return x*f; } void write(int x) { if(x<0) return (void)(putchar('-'),write(-x)); if(x>9) write(x/10); putchar(x%10^48); } void print(int x,char y) { write(x),putchar(y); } #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=1005; int n,k,m,f[105][105][2005][2],maxt,ans; struct node { int a,b,t; } s[105]; bool cmp(node x,node y) { return x.a<y.a; } int main() { freopen("go.in","r",stdin); freopen("go.out","w",stdout); n=read(),k=read(),m=read(); int r; rep(i,1,m) s[i].a=read(),s[i].b=read(),s[i].t=read(),maxt=max(maxt,s[i].t); s[++m]=(node){k,0,0}; sort(s+1,s+m+1,cmp); memset(f,-1,sizeof f); rep(i,1,m) if(s[i].a==k) { for(int j=1;j<=maxt;++j) f[i][i][j][0]=f[i][i][j][1]=0; } for(int len=2;len<=m;++len) for(int l=1;l+len-1<=m;++l) { r=l+len-1; for(int t=1;t<=maxt;++t) { f[l][r][t][0]=f[l][r][t-1][0]; f[l][r][t][1]=f[l][r][t-1][1]; if(t>s[l+1].a-s[l].a&&(~f[l+1][r][t-(s[l+1].a-s[l].a)][0])) { if(s[l].t>=t) { f[l][r][t][0]=max(f[l][r][t][0],f[l+1][r][t-(s[l+1].a-s[l].a)][0]+s[l].b); } else f[l][r][t][0]=max(f[l][r][t][0],f[l+1][r][t-(s[l+1].a-s[l].a)][0]); } if(t>s[r].a-s[l].a&&(~f[l+1][r][t-(s[r].a-s[l].a)][1])) { if(s[l].t>=t) { f[l][r][t][0]=max(f[l][r][t][0],f[l+1][r][t-(s[r].a-s[l].a)][1]+s[l].b); } else f[l][r][t][0]=max(f[l][r][t][0],f[l+1][r][t-(s[r].a-s[l].a)][1]); } if(t>s[r].a-s[r-1].a&&(~f[l][r-1][t-(s[r].a-s[r-1].a)][1])) { if(s[r].t>=t) { f[l][r][t][1]=max(f[l][r][t][1],f[l][r-1][t-(s[r].a-s[r-1].a)][1]+s[r].b); } else f[l][r][t][1]=max(f[l][r][t][1],f[l][r-1][t-(s[r].a-s[r-1].a)][1]); } if(t>s[r].a-s[l].a&&(~f[l][r-1][t-(s[r].a-s[l].a)][0])) { if(s[r].t>=t) { f[l][r][t][1]=max(f[l][r][t][1],f[l][r-1][t-(s[r].a-s[l].a)][0]+s[r].b); } else f[l][r][t][1]=max(f[l][r][t][1],f[l][r-1][t-(s[r].a-s[l].a)][0]); } } } for(int i=1;i<=m;++i) { for(int j=i;j<=m;++j) for(int k=1;k<=maxt;++k) { ans=max(ans,max(f[i][j][k][0],f[i][j][k][1])); } } print(ans,'\n'); return 0; }