这题和失衡天平 (nowcoder.com)这道题很像,都是天平两端需要放东西,那么就把必然需要去维护一个天平两端重量差。但是这道题还有一个技能的使用,使用技能可以将点数加倍。所以这个技能的使用也得需要维护。那么就是维护一个技能的使用次数。
//将手上的牌分成两部分,如果两部分点数相同那么就得到这两部分的牌。
在开始之前还可以全选一些牌将其点数增加二倍。最后要value最大的方式。
状态转移一共有五种情况:
1、不选当前的卡片:dp[i][j][k] = dp[i-1][i][j];
2、选当前的卡片但将其放到点数大的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k+a[i].point]+a[i].v)
4、选当前的卡片但将其放到点数小的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][abs(k-a[i].point)]+a[i].v)
3、选当前的卡片但将其放到点数大的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k+a[i].point]+a[i].v)
5、选当前的卡片但将其放到点数小的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][abs(k-a[i].point)]+a[i].v)
在开始之前还可以全选一些牌将其点数增加二倍。最后要value最大的方式。
状态转移一共有五种情况:
1、不选当前的卡片:dp[i][j][k] = dp[i-1][i][j];
2、选当前的卡片但将其放到点数大的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k+a[i].point]+a[i].v)
4、选当前的卡片但将其放到点数小的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][abs(k-a[i].point)]+a[i].v)
3、选当前的卡片但将其放到点数大的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k+a[i].point]+a[i].v)
5、选当前的卡片但将其放到点数小的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][abs(k-a[i].point)]+a[i].v)
//将手上的牌分成两部分,如果两部分点数相同那么就得到这两部分的牌。 //在开始之前还可以全选一些牌将其点数增加二倍。最后要value最大的方式。 //状态转移一共有五种情况: //1、不选当前的卡片:dp[i][j][k] = dp[i-1][i][j]; //2、选当前的卡片但将其放到点数大的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k+a[i].point]+a[i].v) //4、选当前的卡片但将其放到点数小的那一个里面(不使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][abs(k-a[i].point)]+a[i].v) //3、选当前的卡片但将其放到点数大的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k+a[i].point]+a[i].v) //5、选当前的卡片但将其放到点数小的那一个里面(使用技能):dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][abs(k-a[i].point)]+a[i].v) #include <bits/stdc++.h> using namespace std; #define int long long const int inf = 0x3f3f3f3f; struct Node { int v, t; } a[100+10]; //i代表某个卡片,j代表使用技能的次数,k表示两种中点数的差值。 int dp[100+10][100+10][1301]; int n, k; signed main() { cin>>n>>k; for (int i=1;i<=n;i++) { cin>>a[i].v>>a[i].t; } memset(dp, -inf, sizeof(dp)); dp[0][0][0] = 0; for (int i=1;i<=n;i++) for (int j=0;j<=k;j++) for (int k=0;k<=1301;k++) { dp[i][j][k] = dp[i-1][j][k]; dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][abs(k+a[i].t)]+a[i].v); dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][abs(k-a[i].t)]+a[i].v); if (j!=0) { dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][abs(k+a[i].t*2)]+a[i].v); dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][abs(k-a[i].t*2)]+a[i].v); } } int ans = 0; for (int j=0;j<=k;j++) { ans = max(ans, dp[n][j][0]); } cout<<ans; return 0; }