# 【做题】CSA49F - Card Collecting Game——思维&dp

$n \leq 2\times 10^3, \ \sum a_i \leq 2 \times 10^3, \ \sum b_i \leq 5\times 10^5, \ c_i \geq 0$

#include <bits/stdc++.h>
using namespace std;
const int A = 2010, B = 500010, N = 2010;
int dp[2][A << 2][2][2], bag[B], n, num[A], p, sa, sb, ans;
struct data {
int a,b,c;
bool operator < (const data& x) const {
return c > x.c;
}
} dat[N];
inline void ckmx(int& x,int y) {
x = x < y ? y : x;
}
int main() {
scanf("%d",&n);
for (int i = 1 ; i <= n ; ++ i)
scanf("%d%d%d",&dat[i].a, &dat[i].b, &dat[i].c);
sort(dat+1,dat+n+1);
for (int i = 1 ; i <= n ; ++ i) {
if (dat[i].b / (dat[i].a << 1) - 1 > 0)
num[dat[i].a] += dat[i].b / (dat[i].a << 1) - 1;
sa += dat[i].a;
sb += dat[i].b;
}
p = 1;
memset(dp,-1,sizeof dp);
dp[0][0][0][0] = 0;
for (int i = 1, sum = 0 ; i <= n ; ++ i, p ^= 1) {
memset(dp[p],-1,sizeof dp[p]);
for (int j = 0 ; j <= (sum << 2) ; ++ j)
for (int a = 0 ; a < 2 ; ++ a)
for (int b = 0 ; b < 2 ; ++ b) {
if (dp[p^1][j][a][b] == -1) continue;
for (int k = 0 ; k < 2 * dat[i].a && k <= dat[i].b ; ++ k) {
int tmp = (dat[i].b - k) / (dat[i].a << 1), na = a, nb = b;
if (k == 2 * dat[i].a - 1) {
if (!na) tmp ++;
na ^= 1;
}
if ((dat[i].b - k) % (dat[i].a << 1) == (dat[i].a << 1) - 1) {
if (nb) tmp ++;
nb ^= 1;
}
tmp = tmp * dat[i].c;
ckmx(dp[p][j + k][na][nb], dp[p^1][j][a][b] + tmp);
if (dat[i].b >= 2 * dat[i].a && k <= dat[i].b % (dat[i].a << 1))
ckmx(dp[p][j + k + 2 * dat[i].a][na][nb], dp[p^1][j][a][b] + tmp);
}
}
sum += dat[i].a;
}
bag[0] = 1;
for (int i = 1 ; i < A ; ++ i) {
if (!num[i]) continue;
for (int j = 0 ; j <= sb ; ++ j) {
if (bag[j]) bag[j] = 0;
else {
bag[j] = -1;
if (j >= 2 * i) {
if (bag[j - 2 * i] != -1)
bag[j] = bag[j - 2 * i] + 1;
}
}
}
for (int j = 0 ; j <= sb ; ++ j)
if (bag[j] == -1) bag[j] = 0;
else if (bag[j] <= num[i]) bag[j] = 1;
else bag[j] = 0;
}
p ^= 1;
for (int i = 0 ; i <= (sa << 2) && i <= (sb >> 1) ; ++ i)
for (int a = 0 ; a < 2 ; ++ a)
for (int b = 0 ; b < 2 ; ++ b) {
if (dp[p][i][a][b] == -1) continue;
if (bag[(sb >> 1) - i]) ans = max(ans, dp[p][i][a][b]);
}
printf("%d\n",ans);
return 0;
}

posted @ 2019-01-04 20:59 莫名其妙的aaa 阅读(...) 评论(...) 编辑 收藏