[离散化][区间DP]JZOJ 5770 可爱精灵宝贝
日常黑Pokeman Go
分析
比赛的时候居然打了一个不知道什么鬼的居然离散了时间的DP
正解区间DP,设f[l][r][t]为所用时间为t,经过了l~r,现在在r的最大分值,g[l][r][t],类似,不过在l
预处理:离散化房屋编号
然后从l~r向l-1~r或l~r+1转移
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <memory.h> using namespace std; int f[101][101][4001],g[101][101][4001]; struct Elf { int a,b,t; }a[102]; int n,m,k,mxt,bg; bool Cmp(Elf a,Elf b) { return a.a<b.a; } int main() { freopen("go.in","r",stdin); freopen("go.out","w",stdout); scanf("%d%d%d",&n,&k,&m); for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].t),mxt=max(mxt,a[i].t); a[0].a=k;a[0].b=0;a[0].t=1; sort(a,a+m+1,Cmp); for (int i=0;i<=m;i++) if (a[i].a==k&&a[i].t==1) {bg=i;break;} memset(f,-0x3f,sizeof f); memset(g,-0x3f,sizeof g); f[bg][bg][1]=g[bg][bg][1]=0; for (int t=1;t<=mxt;t++) for (int l=bg;l>=0;l--) for (int r=bg;r<=m;r++) { if (r<m) { f[l][r+1][a[r+1].a-a[r].a+t]=max(f[l][r+1][a[r+1].a-a[r].a+t],f[l][r][t]); f[l][r+1][a[r+1].a-a[l].a+t]=max(f[l][r+1][a[r+1].a-a[l].a+t],g[l][r][t]); if (a[r+1].a-a[r].a+t<=a[r+1].t) f[l][r+1][a[r+1].a-a[r].a+t]=max(f[l][r+1][a[r+1].a-a[r].a+t],f[l][r][t]+a[r+1].b); if (a[r+1].a-a[l].a+t<=a[r+1].t) f[l][r+1][a[r+1].a-a[l].a+t]=max(f[l][r+1][a[r+1].a-a[l].a+t],g[l][r][t]+a[r+1].b); } if (l>0) { g[l-1][r][a[r].a-a[l-1].a+t]=max(g[l-1][r][a[r].a-a[l-1].a+t],f[l][r][t]); g[l-1][r][a[l].a-a[l-1].a+t]=max(g[l-1][r][a[l].a-a[l-1].a+t],g[l][r][t]); if (a[r].a-a[l-1].a+t<=a[l-1].t) g[l-1][r][a[r].a-a[l-1].a+t]=max(g[l-1][r][a[r].a-a[l-1].a+t],f[l][r][t]+a[l-1].b); if (a[l].a-a[l-1].a+t<=a[l-1].t) g[l-1][r][a[l].a-a[l-1].a+t]=max(g[l-1][r][a[l].a-a[l-1].a+t],g[l][r][t]+a[l-1].b); } } int ans=0; for (int t=1;t<=mxt;t++) for (int l=bg;l>=0;l--) for (int r=bg;r<=m;r++) ans=max(ans,max(f[l][r][t],g[l][r][t])); printf("%d",ans); fclose(stdin);fclose(stdout); }
在日渐沉没的世界里,我发现了你。