codeforces 111C/112E Petya and Spiders

题目: Petya and Spiders
传送门:

http://codeforces.com/problemset/problem/111/C

http://codeforces.com/problemset/problem/112/E
分析:
(1)由n·m<=40可以想到状态压缩动态规划,方程很好想,用四进制表示状态,用位运算优化。
(2)由n·m<=40可以想到分类构造公式。
代码:

1)

#include<cstdio>
#include<algorithm>
#define inf 2147483647
int n,m,statenum;
int num[5000],f[2][5000];
bool pd(int state1,int state2){
    int a1=state1%4,b1=0,c1=0,a2=state2%4,b2=0,c2=0;
    state1/=4;state2/=4;
    for(int i(1);i<=2*n;i+=2){
        c1=b1;b1=a1;a1=state1%4;state1/=4;
        c2=b2;b2=a2;a2=state2%4;state2/=4;
        if(b2==0 && b1!=2)return false;
        if(b1==1 && b2!=2)return false;
        if(b1==3 && a1!=2 && c1!=2)return false;
    }
    return true;
}
void solve(){
    statenum=(1<<n*2)-1;
    for(int i(0);i<=statenum;++i)
        {f[0][i]=inf;for(int j=i;j;j>>=2)num[i]+=(j&3)==2;}
    f[0][statenum]=0;
    int x=0,y=1;
    for(int k(1);k<=m+1;++k,x=!x,y=!y)
        for(int i(0);i<=statenum;++i){
            f[y][i]=inf;
            for(int j(0);j<=statenum;++j)
                if(f[x][j]!=inf && pd(i,j))
                    f[y][i]=std::min(f[y][i],f[x][j]+num[i]);
        }
    if(f[y][0]==inf)
        printf("0");else printf("%d",n*m-f[x][0]);
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d %d",&n,&m);
    if(n>m)std::swap(n,m);
    solve();
    //fclose(stdin);fclose(stdout);
    return 0;
}

2)

#include<cstdio>
#define P(x)    return printf("%d\n",m*n-(x)),0;
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    if(n>m)n^=m,m^=n,n^=m;
    switch(n){
        case 1:P((m+2)/3)
        case 2:P((m+2)/2)
        case 3:P(m/4*3+(m%=4)+(m==0))
        case 4:P(m+(m==5||m==6||m==9))
        case 5:P(m/5*6-(m==7)+(m%=5)+1+(m>1))
        case 6:P(10)
    }
    fclose(stdin);fclose(stdout);
}

 

posted @ 2016-03-15 20:54  hjj1871984569  阅读(417)  评论(0编辑  收藏  举报