P3724 [AHOI2017/HNOI2017] 大佬 题解
题目链接:P3724 [AHOI2017/HNOI2017] 大佬
水黑。看到数据范围考虑暴力,跑一下发现 100 天也只够构造出 8.5e6 个不同的数。由于每天的操作除了增加信心值都是等价的,所以可以直接在开头跑一个 dp 求出最多的空闲天数。0 次嘲讽和 1 次嘲讽很好处理,两次嘲讽考虑用一个双指针,注意维护的应该是最大的 嘲讽值-需要使用的天数,因为本来这些天数可以还嘴。爆搜的部分应该使用哈希表判重,因为数据比较水就用了set判重,实测本地机子在满的 100 天的时候跑了 22s,洛谷最大点跑 1s。
代码:
#include<bits/stdc++.h>
#define time(null) chrono::steady_clock::now().time_since_epoch().count()
#define int long long
#define uint unsigned long long
#define debug() cout<<"come here\n"
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define pb push_back
#define Code return
#define by 0
#define MCYYDS ;
using namespace std;
int qpow(int a,int b,int p=INF){int ret=1;while(b){if(b&1)ret=(ret*a)%p;a=(a*a)%p;b>>=1;}return ret;}
inline int read(){int ret=0,f=1;char ch=getchar();while(ch<'0'||ch>'9')f=(ch=='-'?-1:f),ch=getchar();while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();return ret*f;}
inline void write(int x){if(x<0){putchar('-');write(-x);return ;}if(x>9)write(x/10);putchar((char)(x%10+48));}
inline void writech(int x,char ch){write(x);putchar(ch);}
int a[105],w[105],dp[105][105],n,m,mc,mx;
struct node{
int step,f,l;
};
queue<node> q;
set<pii> s;
vector<pii> vc;
void init()
{
q.push({1,1,0});
s.insert({1,1});
vc.pb({1,1});
int cnt=0;
while(q.size())
{
node u=q.front();
q.pop();
if(u.step<mx&&u.f*(u.l+1)<=100000000)
{
s.insert({u.f,u.step+1});
q.push({u.step+1,u.f,u.l+1});
}
if(u.step<mx&&u.l>1&&u.f*u.l<=100000000&&s.find({u.f*u.l,u.step+1})==s.end())
{
s.insert({u.f*u.l,u.step+1});
vc.pb({u.f*u.l,u.step+1});
q.push({u.step+1,u.f*u.l,u.l});
}
// cnt++;
// if(cnt%1000000==0)writech(cnt,'\n');
}
sort(vc.begin(),vc.end());
vector<pii> vc1;
for(auto x:vc)
{
if(vc1.size()==0||vc1.back().first!=x.first)vc1.pb(x);
}
swap(vc,vc1);
}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
n=read(),m=read(),mc=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
}
for(int i=1;i<=n;i++)
{
w[i]=read();
}
memset(dp,0x3f,sizeof(dp));
dp[0][mc]=0;
mx=0;
for(int i=1;i<=n;i++)
{
for(int j=a[i];j<=mc;j++)
{
dp[i][j-a[i]]=min(dp[i][j-a[i]],dp[i-1][j]);
dp[i][min(mc,j-a[i]+w[i])]=min(dp[i][min(mc,j-a[i]+w[i])],dp[i-1][j]+1);
mx=max(mx,i-dp[i][j-a[i]]);
mx=max(mx,i-dp[i][min(mc,j-a[i]+w[i])]);
}
}
// cout<<mx<<'\n';
init();
// cout<<vc.size()<<'\n';
for(int i=1;i<=m;i++)
{
int val=read();
if(val<=mx)
{
puts("1");
continue;
}
bool flag=0;
int mxx=-INF,j=0;
for(int i=vc.size()-1;i>=0;i--)
{
if(vc[i].first<=val&&vc[i].first-vc[i].second+mx>=val)
{
puts("1");
flag=1;
break;
}
while(j<vc.size()&&vc[i].first+vc[j].first<=val)
{
mxx=max(mxx,vc[j].first-vc[j].second);
j++;
}
if(mx+vc[i].first+mxx-vc[i].second>=val)
{
flag=1;
puts("1");
break;
}
}
if(!flag)puts("0");
}
Code by MCYYDS
}

浙公网安备 33010602011771号