洛谷1156 垃圾陷阱 dp

来源:互联网 发布:秦美人神奇升级数据 编辑:程序博客网 时间:2024/06/05 18:46

https://www.luogu.org/problem/show?pid=1156
这个题状态有很多种表示方法:
1. f[i]表示堆到i的高度时最大生命值是多少。
堆 f[i+a[j]]=max( f[ i+a[j] ] , f[i] ) ;
吃 f[i]=f[i]+b[j];
2. bool f[ i ][ j ]表示能否到达 i 高度, j 血量。
然后时间复杂度是n×T×D,由于DP的常数非常小,所以1亿左右的数据是可以大胆跑的。

#include<bits/stdc++.h>#define Max(x,y) x>y?x:yusing namespace std;struct per{    int t,f,h;    void read()    {scanf("%d%d%d",&t,&f,&h);}}p[105];bool cmp(per a,per b){return a.t<b.t;}bool dp[1500][350];int main(){    int d,g;    scanf("%d%d",&d,&g);    for(int i=1;i<=g;i++)        p[i].read();    sort(p+1,p+g+1,cmp);    int n=p[g].t;    int ans=10;    for(int i=0;i<=10;i++)        dp[i][0]=1;    for(int i=1;i<=g;i++)    for(int j=n;j>=0;j--)    for(int k=d;k>=0;k--)    {        if(dp[j][k]&&j>=p[i].t)        {            dp[j][k+p[i].h]=1;            if(k+p[i].h>=d)            {                ans=p[i].t;                printf("%d",ans);                return 0;            }            dp[j+p[i].f][k]=1;        }    }    ans=10;    for(int i=1;i<=g;i++)    {        if(ans>=p[i].t)            ans+=p[i].f;        else break;    }    printf("%d",ans);    return 0;}
1 1
原创粉丝点击