[POI2015]LAS

洛谷题目链接

动态规划:

这里用一种我想不到的思想,我们以美食来转移,设计状态$f[i][S](S\in\{0\sim3\})$其中$S$为$0$时表示第$i$个食物没有被人选,$1$表示被左边的人选了,$2$表示被右边的人选了,$3$表示被两个人同时选中

状态转移有点多,但是挺简单,不多赘述

接下来是美滋滋的代码时间~~~

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#define reg register
using namespace std;
const int N=1e6+5;
int n,a[N],ans[N],f[N][4];//0:á?±???2??? 1:×ó±? 2:óò±? 3:á?±????? 
inline int read()
{
    int x=0,w=1;
    char c=getchar();
    while (!isdigit(c)&&c!='-') c=getchar();
    if (c=='-') c=getchar(),w=-1;
    while (isdigit(c))
    {
        x=(x<<1)+(x<<3)+c-'0';
        c=getchar();
    }
    return x*w;
}
inline bool work(int k)
{
    memset(f,-1,sizeof(f)); f[1][k]=-2;
    for (reg int i=2;i<=n;i++)
    {
        if (~f[i-1][2]&&a[i-1]>=a[i]) f[i][0]=2;
        if (~f[i-1][3]&&a[i-1]>=a[i]*2) f[i][0]=3;
        if (~f[i-1][0]&&a[i]>=a[i-1]) f[i][1]=0;
        if (~f[i-1][1]&&a[i]*2>=a[i-1]) f[i][1]=1;
        if (~f[i-1][2]&&a[i-1]*2>=a[i]) f[i][2]=2;
        if (~f[i-1][3]&&a[i-1]*2>=a[i]) f[i][2]=3;
        if (~f[i-1][0]&&a[i]>=a[i-1]*2) f[i][3]=0;
        if (~f[i-1][1]&&a[i]>=a[i-1]) f[i][3]=1;
    }
    return ~f[n][k];
}
inline void print(int k)
{
    --n;
    for (reg int i=n;~i;i--)
    {
        if (k==1) ans[i]=i%n+1;
        if (k==2) ans[i+1]=i%n+1;
        if (k==3) ans[i]=ans[i+1]=i%n+1;
        k=f[i+1][k];
    }
    for (reg int i=1;i<=n;i++) printf("%d ",ans[i]);
    exit(0);
}
int main()
{
    n=read();
    for (reg int i=1;i<=n;a[i++]=read()); a[++n]=a[1];
    for (reg int i=0;i<4;i++) if (work(i)) print(i);
    puts("NIE");
    return 0;
}

  

posted @ 2019-01-10 18:13  模拟退火  阅读(140)  评论(0编辑  收藏  举报