sdut-2725-The Urge to Merge-状压DP

把数组竖起来,从上往下走。

如果当前位置是竖着乘的,那么第一个点标记为1.否则标记为0.

样例最终的状态为:

0 0 1

0 1 0

1 0 0 

0 0 0

 

#include<iostream>

#include<cmath>

#include<algorithm>

#include<stdio.h>

#include<string.h>

#define max(a,b) ((a)>(b)?(a):(b))

using namespace std;

int maps[1010][11];

int dp[1010][11];

int pan(int x,int y)

{

    int i;

    for(i=0;i<3;i++)

    {

        int tt=(1<<i);

        if((x&tt)&&(y&tt))return 0;

    }

    return 1;

}

int add(int x,int y,int z)

{

    int ans=0;

    int ss[4];

    int i;

    for(i=0;i<3;i++)

    {

        if(x&(1<<i))ss[i+1]=1;

        else ss[i+1]=0;

    }

    for(i=0;i<3;i++)

    {

        if(y&(1<<i))

        {

            ans+=maps[z-1][i+1]*maps[z][i+1];

            ss[i+1]=1;

        }

    }

    int t1,t2;

    t1=t2=0;

    if(ss[1]==0&&ss[2]==0)t1=maps[z][1]*maps[z][2];

    if(ss[2]==0&&ss[3]==0)t2=maps[z][2]*maps[z][3];

    ans+=max(t1,t2);

    return ans;

}

int main()

{

    int i,j,k,n;

    int cas=0;

    while(~scanf("%d",&n)&n)

    {

        cas++;

        memset(maps,0,sizeof(maps));

        memset(dp,0,sizeof(dp));

        for(i=1;i<=3;i++)

        {

            for(j=1;j<=n;j++)

            {

                scanf("%d",&maps[j][i]);

            }

        }

        for(i=1;i<=n;i++)

        {

            for(j=0;j<(1<<3);j++)

            {

                for(k=0;k<(1<<3);k++)

                {

                    if(pan(j,k))

                    {

                        dp[i][j]=max(dp[i-1][k]+add(j,k,i),dp[i][j]);

                    }

                }

            }

        }

        int maxx=-1;

        for(j=0;j<(1<<3);j++)

        {

            maxx=max(maxx,dp[n][j]);

        }

        printf("Case %d: ",cas);

        cout<<maxx<<endl;

    }

}


 

 

你可能感兴趣的:(merge)