uva 10118 - Free Candies

dp

原本在记忆化搜索时想用hash来判重着,写了一个hash版本ac后,在写解题报告时发现其实不用hash也可,

直接改为记忆化搜索果断ac,没想到这么容易就过了,这题一开始想多了。

 这题这么水,实在对不起30s的时限,或许可能存在搜索的版本吧。

164ms

#include <iostream>

#include<cstdio>

#include<cstring>

#define N 41

using namespace std;

int n;

int dp[N][N][N][N];

int mat[N][4];



int DP(int *top,int st,int k)

{



    int &m=dp[top[0]][top[1]][top[2]][top[3]];



    if(m!=-1)

    return m;

    if(top[0]==n&&top[1]==n&&top[2]==n&&top[3]==n||k==5)

    return m=0;

    for(int i=0;i<4;i++)

    if(top[i]<n)

    {

        int bit=1<<mat[top[i]][i];

        top[i]++;

        if(bit&st)

        m=max(m,DP(top,st-bit,k-1)+1);

        else if(k<5)

        m=max(m,DP(top,st+bit,k+1));

        top[i]--;

    }

    return m;

}

int main()

{

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

    {

        memset(dp,-1,sizeof(dp));

        for(int i=0;i<n;i++)

        for(int j=0;j<4;j++)

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

        int top[5]={0};

        printf("%d\n",DP(top,0,0));

    }

    return 0;

}

  hash 版本 460ms

#include <iostream>

#include<cstdio>

#include<cstring>

#define N 41

#define M 1000000

using namespace std;

int n;

int dp[N][N][N][N];

int mat[N][4];

int state[10000000][5],next[10000000],head[M],e;

int hash(int cur)

{

    int v=0;

    for(int i=0;i<5;i++)

    v=v*40+state[cur][i],v%=M;

    return v;

}

bool insert(int u)

{

    int h=hash(u);

    int v=head[h];

    while(v!=-1)

    {

        if(!memcmp(state[u],state[v],sizeof(state[v])))

        return false;

        v=next[v];

    }

    next[u]=head[h];

    head[h]=u;

    return true;

}

int DP(int *top,int st,int k)

{



    int &m=dp[top[0]][top[1]][top[2]][top[3]];



    if(m!=-1)

    {

        top[4]=st;

        memcpy(state[e],top,sizeof(top));

        if(!insert(e))

        return m;

        e++;

    }

    if(top[0]==n&&top[1]==n&&top[2]==n&&top[3]==n||k==5)

    return m=0;

    for(int i=0;i<4;i++)

    if(top[i]<n)

    {

        int bit=1<<mat[top[i]][i];

        top[i]++;

        if(bit&st)

        m=max(m,DP(top,st-bit,k-1)+1);

        else if(k<5)

        m=max(m,DP(top,st+bit,k+1));

        top[i]--;

    }

    return m;

}

int main()

{

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

    {

        memset(dp,-1,sizeof(dp));

        memset(head,-1,sizeof(head));



        e=0;

        for(int i=0;i<n;i++)

        for(int j=0;j<4;j++)

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

        int top[5]={0};

        printf("%d\n",DP(top,0,0));

    }

    return 0;

}

  

你可能感兴趣的:(free)