zoukankan      html  css  js  c++  java
  • HDOJ 6508 Problem I. Spell Boost (01背包/DP)

    链接http://acm.hdu.edu.cn/showproblem.php?pid=6508


    题目:

    Problem Description
    Shadowverse is a funny card game. One day you are playing a round of this game.
    You have n cards, each with two attributes wi and xi. If you use card i, you will cost wi points of power and cause xi damage to the enemy.
    Among them, there are two special types of cards: some cards are magic cards and some have “spell boost effect”. Everytime you have used a magic card, for each unused “spell boost effect” card i: if the the current cost of i (i.e. wi) is positive, then wi will be reduced by 1. Note that some cards may be both
    magic cards and have spell boost effect.
    Now you have W points of power, you need to calculate maximum total damage you can cause.
     
    Input
    Input is given from Standard Input in the following format:
    n W
    w1 x1 is_magic1 is_spell_boost1
    w2 x2 is_magic2 is_spell_boost2
    ...
    ...
    ...
    wn xn is_magicn is_spell_boostn

    Constraints
    1 ≤ n ≤ 500
    0 ≤ W, wi, xi ≤ 500, and all of them are integers.
    is_magici means: If this card is magic card, the value is 1, otherwise the value is 0.
    is_spell_boosti means: If this card has spell boost effect, the value is 1, otherwise 0
     
    Output
    One integer representing the maximum total damage.
     
    Sample Input
    3 3
    3 3 1 1
    2 3 1 1
    1 3 1 1
    4 3
    3 3 1 1
    3 4 1 0
    1 3 0 1
    1 0 1 0
     
    Sample Output
    9
    7
     
     

     

    题意:

    给出四种卡片 既是魔法卡也是增幅卡 是魔法卡不是增幅卡 是增幅卡不是魔法卡 不是增幅卡也不是魔法卡

    每一张卡片都包含两个值 打出牌的代价 和打出牌的价值

    其中魔法卡的作用是使所有未使用的增幅卡代价减1 如果代价已经为0就不减了

    思路:

    从增幅卡和魔法卡的作用中可以看出来 打出这四种牌是有先后顺序的 增幅卡要尽可能后打出 魔法卡要尽可能先打出

    我采用的顺序是 是魔法卡不是增幅卡>是增幅卡不是魔法卡>既是魔法卡也是增幅卡>不是增幅卡也不是魔法卡

    然后采用三维dp来转移 dp[i][j][k]表示的是当前已经打出的伤害和 i表示当前已经打到的第i张牌 j表示当前已经打出的增幅卡的数量 k表示当前已经用掉的代价和

    直接用三维去存储的话存不下 采用了滚动数组去滚掉第一维i(当前的位置只依赖上一位 可以采用滚动数组只记录两个值 i%2和(i-1)%2)


    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn=550;
    int n,W;
    int dp[2][maxn][maxn];
    
    struct node{
        int w,x,vis1,vis2;
    }kk[maxn];
    
    int cmp(node a,node b){
        if(a.vis1!=b.vis1) return a.vis1>b.vis1;
        if(a.vis2!=b.vis2) return a.vis2<b.vis2;
        return a.w<b.w;
    }
    
    int main(){
     //   freopen("1.in","r",stdin);
        while(~scanf("%d%d",&n,&W)){
            for(int i=1;i<=n;i++){
                scanf("%d%d%d%d",&kk[i].w,&kk[i].x,&kk[i].vis1,&kk[i].vis2);
            }
            sort(kk+1,kk+1+n,cmp);
            memset(dp[0],-1,sizeof(dp[0]));
            dp[0][0][0]=0;
          //  cout<<n<<endl;
            for(int i=1;i<=n;i++){
                memset(dp[i%2],-1,sizeof(dp[i%2]));
                for(int j=0;j<=i;j++){
                    for(int k=0;k<=W;k++){
                    //    if(dp[(i-1)%2][j][k]==-1) continue;
                        dp[i%2][j][k]=dp[(i-1)%2][j][k];
                        if(kk[i].vis1==1 && kk[i].vis2==1 && j-1>=0 && k-max(kk[i].w-(j-1),0)>=0 && dp[(i-1)%2][j-1][k-max(kk[i].w-(j-1),0)]!=-1) 
                            dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i-1)%2][j-1][k-max(kk[i].w-(j-1),0)]+kk[i].x); //既是魔法卡也是增幅卡
                        if(kk[i].vis1==0 && kk[i].vis2==1 && k-max(kk[i].w-j,0)>=0 && dp[(i-1)%2][j][k-max(kk[i].w-j,0)]!=-1) 
                            dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i-1)%2][j][k-max(kk[i].w-j,0)]+kk[i].x); //只是增幅卡
                        if(kk[i].vis1==1 && kk[i].vis2==0 && j-1>=0 && k-kk[i].w>=0 && dp[(i-1)%2][j-1][k-kk[i].w]!=-1) 
                            dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i-1)%2][j-1][k-kk[i].w]+kk[i].x); //只是魔法卡
                        if(kk[i].vis1==0 && kk[i].vis2==0 && k-kk[i].w>=0 && dp[(i-1)%2][j][k-kk[i].w]!=-1) 
                            dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i-1)%2][j][k-kk[i].w]+kk[i].x); //什么都不是
                    }
                }
            }
            int ans=0;
            for(int i=0;i<=n;i++){
                for(int j=0;j<=W;j++){
                    ans=max(ans,dp[n%2][i][j]);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    不能初始化ps2020,因为意外的遇到文件尾
    关于在云服务器上邮箱等功能无法正常的解决方法|phpcmsv9
    WAMP环境配置|apache24配置|php7配置|MySQL8配置
    SAP(ABAP) ABAP内部外部数据转换常用function
    移动平台对 META 标签的定义
    JavaScript/Jquery:Validform 验证表单的相关属性解释
    android开发问题 Failed to pull selection 菜鸟记录
    下载android sdk更新包离线安装解决方案
    android:inputType常用取值
    访问IIS元数据库失败解决方法
  • 原文地址:https://www.cnblogs.com/whdsunny/p/10748634.html
Copyright © 2011-2022 走看看