Five in a Row, Again-记录状态的dfs+剪枝

用一个二进制记录当前状态。

二进制中的0代表当前点已经被走过,1代表当前点还未走过。

如果当前二进制之前计算过,且值大于当前值的话,那么就终止不走。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int shuyu[5001];
int n;
int w[101][101];
int e[101][101];
int s[101];
int dp[5001];
void init()
{
    int ns=1;
    for(int i=1;i<=12;i++)
    {
        shuyu[ns]=i;
        ns=ns*2;
    }
    for(int i=1;i<=5000;i++)if(shuyu[i]==0)shuyu[i]=shuyu[i-1];
}
void dos(int num,int exp,int as)
{
    //cout<<num<<" "<<exp<<" "<<as<<endl;
    if(num<dp[as])return ;
    dp[as]=num;
    if(as==0)return;
    int st;
    st=as;
    int ed;
    ed=as;
    while(ed)
    {
        st=ed&(ed-1);
        st=ed-st;
        int pp=shuyu[st];
        if(exp>s[pp])dos(num+w[1][pp],exp+e[1][pp],as-(1<<(pp-1)));
        else dos(num,exp+e[1][pp],as-(1<<(pp-1)));
        ed=ed-st;
    }
}
int main()
{
    int _,i,j;
    init();
    scanf("%d",&_);
    while(_--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&e[i][j]);
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&w[i][j]);
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
        }
        int as=0;
        int ns=1;
        for(i=1;i<=n;i++)
        {
            as+=(1<<(i-1));
        }
        as-=1;
        int leap=1;
        int ans=0;
        while(leap)
        {
            leap=0;
            for(i=2;i<=n;i++)
            {
                if(s[1]<=s[i])continue;
                if((1<<(i-1))&as)
                {
                    s[1]+=e[1][i];
                    as-=(1<<(i-1));
                    ans+=w[1][i];
                    leap=1;
                }
            }
        }
        if(as==0)cout<<ans<<endl;
        else
        {
            dp[as]=ans;
            dos(ans,s[1],as);
            cout<<dp[0]<<endl;
        }
    }
}



你可能感兴趣的:(Five in a Row, Again-记录状态的dfs+剪枝)