插头dp

插头dp从入门到不会


POJ 2411 Mondriaan's Dream

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>

using namespace std;

#define ll long long

const int maxn=12;

ll dp[maxn*maxn+50][(1<<maxn)+50];

int main(){
    int n,m;
    while(scanf("%d %d",&n,&m)==2&&(n||m)){
        if(n<m)swap(n,m);
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        int st=1<<(m+1);
        int cot=0;
        int flag;
        int ne;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                //保证合法递推
                for(int s=0;s<st;s++)if(dp[cot][s]>0){
                    flag=(s>>m)|(s&1);//获取位置位置
                    ne=(s<<1)&(~3);//右移并空出最后两位
                    ne=ne&((1<<(m+1))-1);//保留m位信息
                    if(!flag){

                        if(i!=n-1)dp[cot+1][ne|2]+=dp[cot][s];
                        if(j!=m-1&&((s>>(m-1))&1)==0)dp[cot+1][ne|1]+=dp[cot][s];
                    }
                    else dp[cot+1][ne]+=dp[cot][s];
                }
                cot++;
            }
        }
        printf("%lld\n",dp[cot][0]);
    }
    return 0;
}


HDU 1565 方格取数(1)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>

using namespace std;

#define ll long long

const int maxn=25;

ll grap[maxn][maxn];
ll dp[2][(1<<20)+50];

int main(){
    int n;
    int p;
    while(scanf("%d",&n)==1){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%lld",&grap[i][j]);
            }
        }
        p=0;
        memset(dp,-1,sizeof(dp));
        dp[p][0]=0;
        int st=1<<n;
        ll ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                for(int s=0;s<st;s++)if(dp[p][s]!=-1){
                    if(s&(1<<j))dp[p^1][s^(1<<j)]=max(dp[p][s],dp[p^1][s^(1<<j)]);
                    else if(j!=0&&(s&(1<<(j-1))))dp[p^1][s^(1<<j)]=max(dp[p][s],dp[p^1][s^(1<<j)]);
                    else dp[p^1][s^(1<<j)]=max(dp[p][s]+grap[i][j],dp[p^1][s^(1<<j)]);
                    dp[p^1][s&(~(1<<j))]=max(dp[p][s],dp[p^1][s&(~(1<<j))]);
                }
                p^=1;
            }
        }
        for(int s=0;s<st;s++)ans=max(ans,dp[p][s]);
        printf("%lld\n",ans);
    }
    return 0;
}

HDU 2167 Pebbles

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>

using namespace std;

#define ll long long

const int maxn=16;

int dp[2][(1<<maxn)+50];
int num[maxn+5][maxn+5];
/*int n;
int m;

bool read(){
    n=0;
    m=0;
    char ch;
    int cot=0;
    num[n][m]=0;
    while(cot<2){
        ch=getchar();
        if(ch>='0'&&ch<='9'){
            cot=0;
            num[n][m]=num[n][m]*10+ch-'0';
        }
        else if(ch==' '){
            cot=0;
            num[n][++m]=0;
        }
        else if(ch=='\n'){
            if(!cot)n++;
            m=0;
            num[n][m]=0;
            cot++;
        }
        else if(ch==EOF){
            if(!cot)n++;
            return false;
        }
    }
    return true;
}*/

char s[maxn*maxn];

int main(){
    //printf("%d\n",sizeof(num)+sizeof(dp));
    //freopen("in.txt","r",stdin);
    int ne;
    int flag;
    while(true){
        int n=16;
        int t=0;
        int st=1<<(n+1);
        memset(dp,-1,sizeof(dp));
        int p=0;
        dp[0][0]=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                char ch;
                if(scanf("%d%c",&num[i][j],&ch)==-1)return 0;
                t++;
                if(ch=='\n'&&n==16)n=t;
            }
        }
        st=1<<(n+1);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                for(int s=0;s<st;s++)if(dp[p][s]!=-1){
                    if(j==0)flag=(s>>(n-2))&3;
                    else if(j==n-1)flag=(s>>(n-1))|(s&1);
                    else flag=(s>>(n-2))|(s&1);//获取邻格信息
                    ne=(s<<1)&((1<<(n+1))-1);
                    if(!flag)dp[p^1][ne|1]=max(dp[p^1][ne|1],dp[p][s]+num[i][j]);
                    dp[p^1][ne]=max(dp[p^1][ne],dp[p][s]);
                }
                memset(dp[p],-1,sizeof(dp[p]));
                p^=1;
            }
        }
        int ans=0;
        for(int s=0;s<st;s++)ans=max(dp[p][s],ans);
        printf("%d\n",ans);
    }
    return 0;
}


HDU 1693 Eat the Trees

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <ctime>

using namespace std;

#define ll long long

const int maxn=11;

ll dp[2][532000];
int num[maxn+5][maxn+5];
int pow3[maxn+5];
int pos[maxn+5];
int tmp[maxn+5];

int getstate(int pos[],int m){
    int res=0;
    for(int i=0;i<=m;i++)
        res+=pos[i]*pow3[i];
    return res;
}

int main(){
    pow3[0]=1;
    for(int i=1;i<=maxn+2;i++)pow3[i]=pow3[i-1]*3;
    int t;
    int n,m;
    scanf("%d",&t);
    for(int kase=1;kase<=t;kase++){
        scanf("%d %d",&n,&m);
        //if(n<m)swap(n,m);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                scanf("%d",&num[i][j]);
        int st=pow3[m+1];
        int L,T;
        int p=0;
        dp[0][0]=1;
        for(int i=0;i<n;i++){
            for(int s=0;s<st;s++)if(dp[p][s]){
                int ss=s;
                for(int k=1;k<=m;k++){
                    tmp[k]=ss%3;
                    ss/=3;
                }
                //if(ss!=0)continue;
                tmp[0]=0;
                dp[p^1][getstate(tmp,m)]=dp[p][s];
            }
            memset(dp[p],0,sizeof(dp[p]));
            p^=1;
            for(int j=0;j<m;j++){
                for(int s=0;s<st;s++)if(dp[p][s]){
                    int ss=s;
                    for(int k=0;k<=m;k++){
                        pos[k]=ss%3;
                        ss/=3;
                    }
                    if(num[i][j]==0){
                        memcpy(tmp,pos,sizeof(tmp));
                        tmp[j]=tmp[j+1]=0;
                        dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        continue;
                    }
                    L=j;
                    T=j+1;
                    if(pos[L]==0&&pos[T]==0&&j!=m-1&&i!=n-1&&num[i+1][j]&&num[i][j+1]){
                        memcpy(tmp,pos,sizeof(tmp));
                        tmp[j]=1;tmp[j+1]=2;
                        dp[p^1][getstate(tmp,m)]+=dp[p][s];
                    }
                    if(pos[L]&&pos[T]==0){
                        if(i!=n-1&&num[i+1][j]){
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=pos[L];tmp[j+1]=0;
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                        if(j!=m-1&&num[i][j+1]){
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=0;tmp[j+1]=pos[L];
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                    }
                    if(pos[L]==0&&pos[T]){
                        if(j!=m-1&&num[i][j+1]){
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=0;tmp[j+1]=pos[T];
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                        if(i!=n-1&&num[i+1][j]){
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=pos[T];tmp[j+1]=0;
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                    }
                    if(pos[L]&&pos[T]){
                        if(pos[L]!=pos[T]){
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=tmp[j+1]=0;
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                        else {
                            memcpy(tmp,pos,sizeof(tmp));
                            tmp[j]=tmp[j+1]=0;
                            int cot=0;
                            if(pos[j+1]==1)
                            for(int l=j+2;l<=m;l++){
                                if(pos[l]==1)cot++;
                                else if(pos[l]==2){
                                    if(cot--==0)tmp[l]=1;
                                }
                            }
                            else if(pos[j+1]==2)
                            for(int l=j-1;l>=0;l--){
                                if(pos[l]==2)cot++;
                                else if(pos[l]==1){
                                    if(cot--==0)tmp[l]=2;
                                }
                            }
                            dp[p^1][getstate(tmp,m)]+=dp[p][s];
                        }
                    }
                }
                memset(dp[p],0,sizeof(dp[p]));
                p^=1;
                /*for(int s=0;s<st;s++){
                    printf("%d ",dp[p][s]);
                }
                puts("");*/
            }
        }
        printf("Case %d: There are %lld ways to eat the trees.\n",kase,dp[p][0]);
    }
    return 0;
}



URAL 1519 Formula 1

...待填

URAL 1520 Empire Strikes Back

...待填

FZU 1977 Pandora adventure

...待填

HDU 1964 Pipes

...待填

HDU 3377 Plan

...待填

POJ 1739 Tony's Tour

...待填

POJ 3133 Manhattan Wiring

...待填

ZOJ 3466 The Hive II

...待填

ZOJ 3256 Tour in the Castle

...待填

ZOJ 3213 Beautiful Meadow

...待填

HDU 4285 circuits

...待填

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值