codevs 3325 过山车 DP

来源:互联网 发布:ppt数据分析图 编辑:程序博客网 时间:2024/05/16 12:09

题目

codevs 3325 过山车

题解

和裸的线段覆盖差不多,但是我数组开小了还是没能1A。dp[ i ][ j ]表示覆盖到i的长度,用了j的代价获得的最大快乐值。先把物品按右端点排序之后,依次扫描有没有可以用来转移的物品。也就是说如果存在一个物品m使得m.x+m.len==i(右端点在i),那么:

dp[ i ][ j ]=max(dp[ i ][ j ],dp[ m.x ][ j-m.cost ]+m.val );

(注意dp时两个for和一个while的顺序)因为强制要求覆盖满,所以初始状态只能是dp[ 0 ][ 0 ]=0, 别的都为-1,也是因为这个所以答案不一定是dp[m][C](m是长度,C是最大的代价),需要扫一遍。

代码

//QWsin#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxl=1000+10;const int maxn=10000+10;const int maxm=1000+10;inline int read(){    int ret=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';    return ret;}struct equip{    int x,len,val,cost;    bool operator < (const equip &rhs)const{        return x+len<rhs.x+rhs.len;    }    inline void input(){        x=read();len=read();val=read();cost=read();    }}a[maxn];int dp[maxl][maxm];int main(){    freopen("std.in","r",stdin);    int m,n,C;cin>>m>>n>>C;    for(int i=1;i<=n;i++) a[i].input();    memset(dp,-1,sizeof(dp));    dp[0][0]=0;    sort(a+1,a+n+1);    int p=0;    for(int i=1;i<=n;i++)        while(p+1<=n&&a[p+1].x+a[p+1].len==i)        {            p++;            for(int j=C;j>=a[p].cost;j--)                if(dp[a[p].x][j-a[p].cost]!=-1)                    dp[i][j]=max(dp[i][j],dp[a[p].x][j-a[p].cost]+a[p].val);        }    int ans=-1;    for(int j=1;j<=C;j++) ans=max(ans,dp[m][j]);        printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击