BZOJ3749: [POI2015]Łasuchy

来源:互联网 发布:淘宝助理一键下架宝贝 编辑:程序博客网 时间:2024/06/03 16:18

这题测得我心累…
写了个spj拿着n组数据一组一组手测

其实我都不知道我这样做是不是对的..反正A了不管了…

我们枚举第一个人选哪个,然后f[i][j][k]表示处理完前i个,第i个人选的情况是j(0代表左边,1代表右边),为了使第i个人合法,第i+1个人应该选k(0代表必须左,1代表必须右,2代表两个都行)这种情况是否可行
用一个pre记录转移,dp完前n-1个后,对于一个合法的f[n-1][j][k],我们恢复每个人选的情况,看第n个人可以选哪个,选完再判一下第一个人是否合法
…..
感觉好像有哪里不太对劲…不管了反正A了….

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 1000005;int n;ll a[maxn];//           1  i i+1bool f[maxn][2][3];int pre[maxn][2][3];inline int id(const int x,const int y){ return x*10+y; }int now,ti,i,j;inline void trans(const int i2,const int j2){    if(f[now][i2][j2]) return;    f[now][i2][j2]=true;    pre[now][i2][j2]=id(i,j);}int t[maxn];bool judge(){    int s1=a[1],s2=a[2];    if(t[n]) s2<<=1;    if(!t[2]) s1<<=1;    if(s1>=s2&&!t[1]) return true;    if(s2>=s1&&t[1]) return true;    return false;}int main(){    scanf("%d",&n);    for(i=1;i<=n;i++) scanf("%d",&a[i]);    for(ti=1;ti>=0;ti--)    {        if(!ti)        {            memset(f,false,sizeof f);            if(a[1]>=a[2]) f[1][0][2]=true;            else if(a[1]*2>=a[2]) f[1][0][0]=true;        }        if(ti)        {            memset(f,false,sizeof f);            if(a[2]>=a[1]*2) f[1][1][2]=true;            else if(a[2]>=a[1]) f[1][1][2]=true;            else if(a[2]*2>=a[1]) f[1][1][1]=true;        }        for(int x=2;x<n;x++)        {            now=x;            for(i=0;i<2;i++) for(j=0;j<3;j++) if(f[now-1][i][j])            {                ll s1=a[x],s2=a[x+1];                if(i) s2<<=1;                if(j!=2)                {                    if(!j)                    {                        if(s1>=s2) trans(0,2);                        else if((s1<<1)>=s2) trans(0,0);                    }                    else                    {                        if(s2>=(s1<<1)) trans(1,2);                        else if(s2>=s1) trans(1,1);                    }                }                else                {                    if(s1>=s2) trans(0,2);                    else if((s1<<1)>=s2) trans(0,0);                    if(s2>=(s1<<1)) trans(1,2);                    else if(s2>=s1) trans(1,1);                }            }        }        t[1]=-1;        for(i=0;i<2;i++) for(j=0;j<3;j++) if(f[n-1][i][j]&&t[1]==-1)        {            int tti=i,tj=j; now=n-1; t[1]=ti;            while(now!=1)            {                t[now]=tti;                int ttj=pre[now][tti][tj]%10;                tti=pre[now][tti][tj]/10; tj=ttj;                now--;            }            ll s1=a[n],s2=a[1];            if(t[n-1]) s2<<=1;            if(!t[1]) s1<<=1;            if(s1>=s2&&(!j||j==2))             {                t[n]=0;                if(judge()) break;            }            if(s2>=s1&&j)             {                t[n]=1;                if(judge()) break;            }            t[1]=-1;        }        if(t[1]!=-1)        {            for(i=1;i<n;i++) printf("%d ",i+t[i]>n?1:i+t[i]);            printf("%d\n",i+t[i]>n?1:i+t[i]);            break;        }    }    if(t[1]==-1) puts("NIE");    return 0;}
原创粉丝点击