[THUPC2017] 钦妹的玩具商店 题解
FXT1110011010OI · · 题解
思路分析
暴力 DP 卡过。
设 DP 数组
转移直接使用多重背包二进制优化即可。具体见代码。
题目还有
对于相同的
注意 不要随意将 DP 数组进行空间优化,压缩成一维。因为这样就无法处理之后的
时间复杂度:DP 时用二进制优化,为 这都能过,你谷评测机是真的强。
代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010, mod = 1e8 + 7;
int c[N], v[N];
vector<PII> a[N];
int f[N][N], g[N][N];
int mx[N];
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i ++ ) a[i].clear();
memset(f, 0, sizeof f);
memset(g, 0, sizeof g);
for (int i = 1; i <= n; i ++ ) scanf("%d", &c[i]);
for (int i = 1; i <= n; i ++ ) scanf("%d", &v[i]);
for (int i = 1; i <= n; i ++ )
{
int t;
scanf("%d", &t);
int now = 1;
while (now <= t)
{
a[i].push_back({c[i] * now, v[i] * now});
t -= now, now *= 2;
}
if (t) a[i].push_back({c[i] * t, v[i] * t});
}
for (int i = 1; i <= n; i ++ )
{
for (int j = m; ~j; j -- ) f[i][j] = f[i - 1][j];
for (auto j : a[i])
for (int k = m; k >= j.first; k -- )
f[i][k] = max(f[i][k], f[i][k - j.first] + j.second);
}
for (int i = n; i; i -- )
{
for (int j = m; ~j; j -- ) g[i][j] = g[i + 1][j];
for (auto j : a[i])
for (int k = m; k >= j.first; k -- )
g[i][k] = max(g[i][k], g[i][k - j.first] + j.second);
}
int pre = 0;
while (q -- )
{
memset(mx, 0, sizeof mx);
int x, y;
scanf("%d%d", &x, &y);
int l = min((x + pre - 1) % n + 1, (y + pre - 1) % n + 1);
int r = max((x + pre - 1) % n + 1, (y + pre - 1) % n + 1);
for (int i = 0; i <= m; i ++ )
for (int j = 0; i + j <= m; j ++ )
mx[i + j] = max(mx[i + j], f[l - 1][i] + g[r + 1][j]);
int sum = 0, xorsum = 0;
for (int i = 1; i <= m; i ++ )
{
sum = (sum + mx[i]) % mod;
xorsum ^= mx[i];
}
printf("%d %d\n", sum, xorsum);
pre = sum;
}
}
return 0;
}