BZOJ3749 : [POI2015]Łasuchy

设f[i][S]表示第i份食物被两个人吃的状态为S是否有可能,枚举f[1][]的情况后检验

f[i][0]=(f[i-1][1]&a[i-1]>=a[i])|(f[i-1][3]&a[i-1]>=2*a[i])

f[i][1]=(f[i-1][1]&2*a[i-1]>=a[i])|(f[i-1][3]&a[i-1]>=a[i])

f[i][2]=(f[i-1][0]&a[i]>=a[i-1])|(f[i-1][2]&2*a[i]>=a[i-1])

f[i][3]=(f[i-1][0]&a[i]>=2*a[i-1])|(f[i-1][2]&a[i]>=a[i-1])

 

#include<cstdio>
#define N 1000010
int n,i,j,S,a[N],g[N][4],ans[N],c[N];
bool f[N][4];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
bool dp(int S){
  for(i=1;i<=n;i++)for(j=0;j<4;j++)f[i][j]=0;
  f[1][S]=1;
  for(i=2;i<=n;i++){
    if(f[i-1][1]&a[i-1]>=a[i])f[i][0]=1,g[i][0]=1;
    else if(f[i-1][3]&a[i-1]>=2*a[i])f[i][0]=1,g[i][0]=3;
    if(f[i-1][1]&2*a[i-1]>=a[i])f[i][1]=1,g[i][1]=1;
    else if(f[i-1][3]&a[i-1]>=a[i])f[i][1]=1,g[i][1]=3;
    if(f[i-1][0]&a[i]>=a[i-1])f[i][2]=1,g[i][2]=0;
    else if(f[i-1][2]&2*a[i]>=a[i-1])f[i][2]=1,g[i][2]=2;
    if(f[i-1][0]&a[i]>=2*a[i-1])f[i][3]=1,g[i][3]=0;
    else if(f[i-1][2]&a[i]>=a[i-1])f[i][3]=1,g[i][3]=2;
  }
  for(j=0;j<4;j++)f[0][j]=f[n][j],f[1][j]=0;
  i=1;
  if(f[i-1][1]&a[i-1]>=a[i])f[i][0]=1,g[i][0]=1;
  else if(f[i-1][3]&a[i-1]>=2*a[i])f[i][0]=1,g[i][0]=3;
  if(f[i-1][1]&2*a[i-1]>=a[i])f[i][1]=1,g[i][1]=1;
  else if(f[i-1][3]&a[i-1]>=a[i])f[i][1]=1,g[i][1]=3;
  if(f[i-1][0]&a[i]>=a[i-1])f[i][2]=1,g[i][2]=0;
  else if(f[i-1][2]&2*a[i]>=a[i-1])f[i][2]=1,g[i][2]=2;
  if(f[i-1][0]&a[i]>=2*a[i-1])f[i][3]=1,g[i][3]=0;
  else if(f[i-1][2]&a[i]>=a[i-1])f[i][3]=1,g[i][3]=2;
  return f[1][S];
}
int main(){
  read(n);
  for(i=1;i<=n;i++)read(a[i]);a[0]=a[n];
  for(S=0;S<4;S++)if(dp(S))break;
  if(S==4)puts("NIE");
  else{
    ans[1]=S;
    for(i=n,j=g[1][S];i>1;j=g[i--][j])ans[i]=j;
    if(ans[1]==1||ans[1]==3)c[1]=1;
    if(ans[1]==2||ans[1]==3)c[n]=1;
    for(i=2;i<=n;i++){
      if(ans[i]==1||ans[i]==3)c[i]=i;
      if(ans[i]==2||ans[i]==3)c[i-1]=i;
    }
    for(i=1;i<=n;i++)printf("%d ",c[i]);
  }
  return 0;
}

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值