积木 BD202205
似乎测试数据太弱了
题意 给定a[1..10] <= 1e11, h <= 1e12
对于任意b, 求min(max(sum b[i] * i), h), b[i] \in [0,a[i]]
b[i]是整数
2s
512mb
我的思路
似乎没官方题解
我最开始想的用bitmask, 去做 dp, 按照不同顺序,有贪心最多
但是实际上 h=10, a[2] = 3, a[3] = 3时
选2个2和2个3刚好拼成10, 而贪心 会是 3 * 2 + 1 * 3
或者 0 * 2 + 3 * 3
都无法达到最大
然后测试数据弱就过了,根据讨论区 说,只要所有加起来都能过测试,这是什么坑爹的出题人和数据,
新的思路
lcm 下的表示
如果暴力 dp就是dp[前i个][和为j] = 能否达到
LCM = lcm(1..10)
而注意到 如果
dp[i][j]
可以从 dp[i-1][j0]
,达到
dp[i-1][j0+LCM]
是可达的
j >= j0+LCM
这三个条件同时满足, 则dp[i][j]
可以从 dp[i-1][j0+LCM]
达到!
因此 变成 dp[前i个用完][val%LCM = j]= 最大可达的val (且<=h)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i,a,n) for (ll i=a;i<(ll)n;i++) ll read(){ll r;scanf("%lld",&r);return r;} const ll INF = 0x3f3f3f3f'3f3f3f3f; const int bound = 2520; ll cnt[20]; int main(){ ll h = read(); rep(i,1,10+1) cnt[i] =read(); auto maxt = [&](ll v,ll i){ return min(cnt[i], (h-v)/i); }; auto setmax = [](ll &a,ll b){a=max(a,b);}; vector<ll> mx(bound, -INF); mx[0] = 0; rep(i,1,10+1) { vector<ll> newmx(bound, -INF); rep(modv,0,bound) if(mx[modv] != -INF){ ll v = mx[modv]; ll maxk = maxt(v,i); rep(k,max((ll)0,maxk+1-bound), maxk+1){ ll newv = v + i * k; setmax(newmx[newv%bound],newv); } } mx=newmx; } ll ans = 0; rep(modv,0,bound) if(mx[modv] != -INF) ans = max(ans,mx[modv]); printf("%lld\n",ans); return 0; }
|
感觉 似乎还是没有完全的证明到