UESTC 1608状压+记忆化搜索

题目链接:http://acm.uestc.edu.cn/#/problem/show/1608

状态压缩,0代表已经取了这个人,1代表没有取,一开始全1状态,

复杂度约为:O(2^n*n*n) 

#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
#include <cstdlib>

using namespace std;

int N,M,T;
int A[22][22][22];
int dp[1<<22];
bool vis[1<<22];

int  dfs(int x)
{
    if(dp[x]!=-1)return dp[x];
    int i,j,k;

    for(i=0;i<N-2;i++)
    {
        if(x&(1<<i))break; //找到一个可以放的位置(其实就是组)
    }
    for(int j=i+1;j<N-1;j++)
    {
        if(x&(1<<j))
            for(int k=j+1;k<N;k++)
                if(x&(1<<k))
                    dp[x] = max(dp[x],dfs(x^(1<<i)^(1<<j)^(1<<k)) + A[i][j][k]);//从i+1往后找到合适的j和k 在前一个状态完成后才能取得当前最大值
    }
    return dp[x];
}


int main() {

    int a,b,c,d;
    while(~scanf("%d",&N))
    {
        memset(dp,-1,sizeof(dp));

        int M = N*(N-1)*(N-2);
        M/=6;
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            A[a-1][b-1][c-1]=d;
        }

        dp[0]=0;//最后全满的临界状态为0 

        cout<<dfs((1<<N)-1)<<endl;
    }

    return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值