loj2021 「HNOI2017」大佬

there

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<int,int> par;
int n, m, mc, maxDay, maxLife, a[105], b[105], dp[105][105], c[105], cnt;
map<par,bool> mp;
par q[5000005];
struct Node{
	int x, y, z;
};
queue<Node> d;
void bfs(){
	d.push((Node){1, 1, 0});//用一天能打出来1的成绩。如果不打,那等级就是0
	while(!d.empty()){
		Node x=d.front();
		d.pop();
		if(x.x<maxDay){
			d.push((Node){x.x+1, x.y, x.z+1});
			if(x.z>1 && (ll)x.y*x.z<=maxLife && !mp.count(make_pair(x.y*x.z, x.z))){
				Node t=(Node){x.x+1, x.y*x.z, x.z};
				q[++cnt] = make_pair(t.y, t.x);
				mp[make_pair(t.y, t.z)] = true;
				d.push(t);
			}
		}
	}
}
int main(){
	cin>>n>>m>>mc;
	for(int i=1; i<=n; i++)
		scanf("%d", &a[i]);
	for(int i=1; i<=n; i++)
		scanf("%d", &b[i]);
	for(int i=1; i<=m; i++){
		scanf("%d", &c[i]);
		maxLife = max(maxLife, c[i]);
	}
	memset(dp, 0xcf, sizeof(dp));
	dp[0][mc] = 0;
	for(int i=1; i<=n; i++)
		for(int j=0; j<=mc-a[i]; j++){
			dp[i][j] = max(dp[i-1][j+a[i]]+1, dp[i][j]);
			dp[i][min(j+b[i], mc)] = max(dp[i-1][j+a[i]], dp[i][min(j+b[i], mc)]);
		}
	for(int i=1; i<=n; i++)
		for(int j=0; j<=mc; j++)
			maxDay = max(maxDay, dp[i][j]);
	bfs();
	sort(q+1, q+1+cnt);
	for(int i=1; i<=m; i++){
		if(c[i]<=maxDay){
			printf("1
");
			continue;
		}
		// cout<<"FaQ
";
		int j=1, maxn=-0x3f3f3f3f;
		bool flag=false;
		for(int k=cnt; k>=1; k--){
			while(j<=cnt && q[k].first+q[j].first<=c[i]){
				maxn = max(maxn, q[j].first-q[j].second);
				j++;
			}
			if(maxn+maxDay+q[k].first-q[k].second>=c[i]){
				flag = true;
				break;
			}
			if(q[k].first<=c[i] && maxDay-q[k].second+q[k].first>=c[i]){
				flag = true;
				break;
			}
		}
		if(flag)	printf("1
");
		else	printf("0
");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8823242.html