题意:
$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 ight brace$。
代码:
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("********* ") 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 ",ans); 118 } 119 }