Spell Boost HDU-6508(dp)

题意:

$n$张卡片,每张卡片有4个属性$w,x,isMagic,isSpellBoost$分别表示花费,伤害,是否为魔法卡,是否为作用卡。如果使用一张魔法卡,可以使所有未使用的作用卡的费用减$1$,已知有$W$的钱,求造成的最大伤害。

思路:

$dp[i][j]$表示使用了$i$张魔法卡,花费$j$造成的最大伤害。

$m=1$表示魔法卡,$b=1$表示作用卡。

那么对于每一张卡片,需要的花费是:$cost=w-(i-m)*b$。

转移方程:$dp[i][j]=max  \left \lbrace dp[i][j],dp[i-m][j-cost]+x \right\rbrace$。

代码:

  1 #include<bits/stdc++.h>
  2 #include <set>
  3 #include <map>
  4 #include <stack>
  5 #include <cmath>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 
 14 #define ll long long
 15 #define pll pair<ll,ll>
 16 #define pii pair<int,int>
 17 #define bug printf("*********\n")
 18 #define FIN freopen("input.txt","r",stdin);
 19 #define FON freopen("output.txt","w+",stdout);
 20 #define IO ios::sync_with_stdio(false),cin.tie(0)
 21 #define ls root<<1
 22 #define rs root<<1|1
 23 #define Q(a) cout<<a<<endl
 24 
 25 using namespace std;
 26 const int inf = 2e9 + 7;
 27 const ll Inf = 1e18 + 7;
 28 const int maxn = 1e3 + 5;
 29 const int mod = 1e9 + 7;
 30 
 31 ll gcd(ll a, ll b)
 32 {
 33     return b ? gcd(b, a % b) : a;
 34 }
 35 
 36 ll lcm(ll a, ll b)
 37 {
 38     return a / gcd(a, b) * b;
 39 }
 40 
 41 ll read()
 42 {
 43     ll p = 0, sum = 0;
 44     char ch;
 45     ch = getchar();
 46     while (1)
 47     {
 48         if (ch == '-' || (ch >= '0' && ch <= '9'))
 49             break;
 50         ch = getchar();
 51     }
 52 
 53     if (ch == '-')
 54     {
 55         p = 1;
 56         ch = getchar();
 57     }
 58     while (ch >= '0' && ch <= '9')
 59     {
 60         sum = sum * 10 + ch - '0';
 61         ch = getchar();
 62     }
 63     return p ? -sum : sum;
 64 }
 65 
 66 struct node
 67 {
 68     int id,w,x,m,s;
 69 }p[maxn];
 70 
 71 bool cmp(const node &a,const node &b)
 72 {
 73     if(a.m==b.m)
 74     {
 75         if(a.s==b.s)
 76         {
 77             return a.w<b.w;
 78         }
 79         return a.s<b.s;
 80     }
 81     return a.m>b.m;
 82 }
 83 
 84 int n,W;
 85 int dp[maxn][maxn];
 86 
 87 int main()
 88 {
 89     while(~scanf("%d %d",&n,&W))
 90     {
 91         memset(dp,-1,sizeof dp);
 92         for(int i=1;i<=n;++i)
 93         {
 94             scanf("%d %d %d %d",&p[i].w,&p[i].x,&p[i].m,&p[i].s);
 95             p[i].id=i;
 96         }
 97         sort(p+1,p+1+n,cmp);
 98         int ans=0;
 99         dp[0][0]=0;
100         for(int i=1;i<=n;++i)
101         {
102             for(int j=W;j>=0;--j)
103             {
104                 for(int k=n;k>=0;--k)
105                 {
106                     int w=max(p[i].w-(k-p[i].m)*p[i].s,0);
107                     if(j-w<0)   continue;
108                     if(k-p[i].m<0)  continue;
109                     if(dp[k-p[i].m][j-w]==-1)   continue;
110               //      cout<<" k j "<<k<<" "<<j<<" "<<w<<" "<<p[i].id<<endl;
111                     dp[k][j]=max(dp[k][j],dp[k-p[i].m][j-w]+p[i].x);
112              //       cout<<k<<" "<<j<<" "<<dp[k][j]<<endl;;
113                     ans=max(ans,dp[k][j]);
114                 }
115             }
116         }
117         printf("%d\n",ans);
118     }
119 }

 

posted @ 2020-03-30 11:10  Big-Kelly  阅读(138)  评论(0编辑  收藏  举报