[AH2017&HNOI2017]兄

\(ProblemLink \)

中には、問題の解決策を養います

私たちはあなたの自信の値を観測して、1,3,4,5の動作が影響を受けている行くように実行されません。

そして、1,3,4,5-操作は、操作の日数とは無関係です。

だから我々は、単純な行うことができます\(DP \)の質問の数は、あなたができるだけ水を磨くように、。

\([I]、[J F \]) セクションを表し\(Iは\)生きていると信頼値の日\(J \)空いた他の操作を実行するまでの日数。

\(DP \)式は次のよう

水の問題を磨くないでください。

\(F [I] [JA [I] = MAX(F [I] [JA [I]、F [I-1]〜[J] +1)\)

ブラシの水問題

\(F [i]が[分(JA [I] + [I]、MC)W] = MAX(F [I-1]〜[J]、F [i]が[分(JA [i]が+ W [I ]、MC)])\)

最後のスイープ再び、アイドル最大日数を描く\(D \)

質問は、あなたのD-日間の動作にフリーとなり、あなたは兄が嫌い勝つことができます。

その後のは、再びそれを探してみましょう、すべての可能な状態が損傷によってソート、検索のうち、(傷害、日数の必要数を)タプル

するために怪我を設定します(F_iとを\)\として消費し、\(S_I \を)

我々は3つのオプションがあり、

まず、兄を嫌いではありません。

分析\(D> = C \)をすることができます。

第二に、かつて兄を憎みます。

再び掃引するか否かを判断する\(C-F_J \ルD -s_i \) 、すなわち時間Haizuiの残りの部分。

\(F_J \)にする(\ルC \)を\

第三に、2つの首長が嫌い

二つの操作がされると仮定することができる嫌い\((F_A、S_A)、 (F_B、S_B)\)

操作は、以下の条件を満たしています。

\(\巨大​​\のlbrace_ {F_A + F_B \ルC} ^ {C-F_A、F_B \ルD-S_A、S_B} \)

式に実際換算で\(C-F_A + S_A \ルD + F_B-S_B \)

だから我々は、二つのポインタの維持(A、B \)\を

確保\(F_A + F_B \ルC \) 維持の前提の下で\(F_B-S_B \)最大。

あなたがすることができます\(O(N)は、\)完了です。

/*
@Date    : 2019-07-30 15:10:45
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
#define _d(i) all[i].second
#define _f(i) all[i].first
const int MAXN=117;
int f[MAXN][MAXN];
int n,m,mc,a[MAXN],w[MAXN],C[MAXN];
int mx;
int mxx;
#define mp(a,b) make_pair(a,b)
const int mod=19491001;
struct hashtable{
    struct edge{
        int x,y,nxt;
    }e[1111111];
    int head[mod+10],cnt;
    hashtable(){memset(head,cnt=-1,sizeof head);}
    inline int hash_func(int x,int y)
    {
        return (1ll*x*107+y)%mod+1;
    }
    inline void add(int x,int y){
        int hashval=hash_func(x,y);
        e[++cnt]=(edge){x,y,head[hashval]},head[hashval]=cnt;
    }
    bool find(int x,int y)
    {
        int hval=hash_func(x,y);
        for(int i=head[hval];~i;i=e[i].nxt)
            if(e[i].x==x&&e[i].y==y)
                return 1;
        return 0;
    }
}ht;
struct node{int i,F,L;};
queue<node>Q;
vector< pair<int,int> >all;
signed main(void)
{
    #ifndef ONLINE_JUDGE
    File("file");
    #endif
    n=gi,m=gi,mc=gi;
    for(int i=1;i<=n;++i)a[i]=gi;
    for(int i=1;i<=n;++i)w[i]=gi;
    for(int i=1;i<=m;++i)mx=max(mx,C[i]=gi);
    for(int i=1;i<=n;++i)
        for(int j=a[i];j<=mc;++j)
            f[i][j-a[i]]=max(f[i-1][j]+1,f[i][j-a[i]]),
            f[i][min(j-a[i]+w[i],mc)]=max(f[i-1][j],f[i][min(j-a[i]+w[i],mc)]);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=mc;++j)
            mxx=max(mxx,f[i][j]);
    Q.push((node){1,1,0});
    while(!Q.empty())
    {
        node u=Q.front();Q.pop();
        if(u.i==mxx)continue;
        Q.push((node){u.i+1,u.F,u.L+1});
        if(u.L>1&&1ll*u.F*u.L<=1ll*mx&&!ht.find(u.F*u.L,u.i+1))
        {
            Q.push((node){u.i+1,u.F*u.L,u.L});
            all.push_back(make_pair(u.F*u.L,u.i+1));
            ht.add(u.F*u.L,u.i+1);
        }
    }
    sort(all.begin(),all.end());
    for(int i=1;i<=m;++i)
    {
        if(C[i]<=mxx){puts("1");continue;}
        bool flag=0;
        for(int j=all.size()-1,maxn=-1e9,k=0;j>=0;--j)
        {
            while(k<all.size()-1&&_f(k)+_f(j)<=C[i])maxn=max(maxn,_f(k)-_d(k)),++k;
            if(_f(j)<=C[i]&&mxx+_f(j)-_d(j)>=C[i]){flag=1;break;}
            if(mxx+_f(j)-_d(j)+maxn>=C[i]){flag=1;break;}
        }
        cout<<flag<<endl;
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/LLCSBlog/p/11275689.html