bzoj1802 [Ahoi2009]checker (recursive)

If two adjacent squares are red (except the first square), then we can deduce that all squares can be red. The number of steps used is f[i]=f[i+1]+f[i+2] or f[i]=f[i-1]+f[i-2]. Then the answer to the first question must be 0, and the second question can recursively take the minimum value.

If any two adjacent squares are different from red, then we just look at the statistical answer of what color are all the squares that have chess pieces.
Complexity The (n2)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1010
#define ll long long
#define inf 0x3f3f3f3f
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n;ll a[N];
bool flag=0;
inline ll cal(ll x){return x<0?1e16:x;}
int main(){
//  freopen("a.in","r",stdin);
    n=read();memset(a,127,sizeof(a));
    for(int i=1;i<=n;++i){
        if(read()) a[i]=1;if(i>2&&a[i]==1&&a[i-1]==1) flag=1;
    }if(!flag){
        int x=0,y=0;
        for(int i=2;i<=n;i+=2) if(a[i]==1) ++y;else ++x;
        printf("%d\n%d\n",x,y);return 0;
    }for(int i=3;i<=n;++i){
        if(a[i]!=1||a[i-1]!=1) continue;
        for(int j=i-2;j>=2;--j) a[j]=min(a[j],cal(a[j+1]+a[j+2]));
        for(int j=i+1;j<n;++j) a[j]=min(a[j],cal(a[j-1]+a[j-2]));
    }puts("0");ll res=0;
    for(int i=2;i<n;i+=2) res+=a[i];
    printf("%lld\n",res);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324834737&siteId=291194637