題目鏈接:點我啊╭(╯^╰)╮
題目大意:
中文題
解題思路:
發現自己的自信值是否足夠和能否打敗大佬是兩碼事
因此可以先用一個 求出最多可以騰出多少天可以來蓄力,設最多有 天
然後接下來肯定是用一個 求出最終答案,但是這個 用什麼來最爲轉移的數據完全不知道
那麼假設有一個 ,表示用 天,可以造成 的攻擊
也就是說如果知道了所有的 ,就可以進行 了(雖然還不知道怎麼 )
很明顯,可以通過 來求出所有 ,那麼如何計算時間複雜度呢?
可以猜測必須通過這些 進行 ,那麼這些 的數量一定不會太大
所以可以直接 就完事了!注意要去重
如果最多隻能攻擊一次,則只需滿足 即可
如果能攻擊兩次,設對應的兩個 爲
暴力枚舉肯定不行, 那麼思考是否能滿足決策優化
對 進行從小到大的排序,則隨着 的增大, 一直減少
但如果這樣枚舉會產生不合法的 ,只需要對 從大到小枚舉即可
特別注意要特判單獨的 是否滿足 以及 的情況
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int maxn = 105;
int n, m, mc, a[maxn], w[maxn], c[maxn];
int D, dp[maxn][maxn], mxc, top;
map <pii, int> mp;
struct node{
int d, f, l;
bool operator < (const node A) const {
if(f == A.f) return d < A.d;
return f < A.f;
}
} st[2000005];
int getD(){
for(int i=1; i<=n; i++)
for(int j=a[i]; j<=mc; j++){
dp[i][j-a[i]] = max(dp[i][j-a[i]], dp[i-1][j] + 1);
int nj = min(mc, j - a[i] + w[i]);
dp[i][nj] = max(dp[i][nj], dp[i-1][j]);
}
int ret = 0;
for(int i=1; i<=n; i++)
for(int j=0; j<=mc; j++)
ret = max(ret, dp[i][j]);
return ret;
}
void bfs(){
queue <node> q;
node u = {1, 1, 0}, v;
q.push(u);
while(q.size()){
u = q.front(), q.pop();
if(u.d >= D) continue;
q.push({u.d + 1, u.f, u.l + 1});
if(u.l <= 1 || 1ll * u.f * u.l > 1ll * mxc) continue;
if(mp[{u.d + 1, u.f * u.l}]) continue;
v.d = u.d + 1, v.f = u.f * u.l, v.l = u.l;
q.push(v), mp[{u.d + 1, u.f * u.l}] = 1;
st[++top] = {u.d + 1, u.f * u.l};
}
}
signed main() {
scanf("%d%d%d", &n, &m, &mc);
for(int i=1; i<=n; i++) scanf("%d", a+i);
for(int i=1; i<=n; i++) scanf("%d", w+i);
for(int i=1; i<=m; i++) scanf("%d", c+i), mxc = max(mxc, c[i]);
D = getD();
bfs();
sort(st+1, st+1+top);
for(int i=1; i<=m; i++){
int f = 0, mx = -1e9;
if(c[i] <= D) {
printf("%d\n", 1);
continue;
}
for(int f1=top, f2=1; f1; f1--){
while(f2 < top && st[f1].f + st[f2].f <= c[i])
mx = max(mx, st[f2].f - st[f2].d), f2++;
if(st[f1].f+D-st[f1].d+mx >= c[i]) {
f = 1;
break;
}
if(st[f1].f<=c[i] && st[f1].f-st[f1].d+D >= c[i]) {
f = 1;
break;
}
}
printf("%d\n", f);
}
}