初识状压dp

状压dp就是用一个集合来表示状态的DP,可以优化时间复杂度,而这个集合就是我们的二进制数,每一位二进制有0和1两种状态,可以表示用或者不用 等对立的状态,所以学习状压dp的时候还需要了解位运算的知识
比较常用的位运算

if(i >> j & 1) {};//判断i的第j位上是不是1

i - (1 << j);   //在i的二进制表示中第j位是1的条件下,减去i的二进制表示中第j位的1;
//后续用到了更新

举例来说:题目
在这道题中,我们要求规定了起点和终点的哈密顿路径,如果直接dfs枚举的话,少说也有20!的时间复杂度,20!=2,432,902,008,176,640,000 神仙也怕要算10s, 所以是暴力的做法是不可行的,在yxc大佬的讲解下,如果我们已知了在某一个点j,已经用过的数,那么就可以推出下一个点走k时的‬价值,即状态转移方程是:
dp[state][j]=min(dp[state][k]+mp[k][j],dp[state][j]);
state是一个是十进制数,他的二进制就是我们当前要计算的状态,用1表示这一位用了,0表示这一位没用。
在这种思路下 ,我们就只需要枚举状态 当前要计算的点和转移到当前点,时间差不多 (1<<n)2020; 由于n最大为20 所以结果是419430400‬ 和20!比起来好的不是一点两点。所以这思路就是离谱!
AC代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<time.h>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<functional>
#include<stack>
#include<map>
#include<queue>
#include<cstring>
#define mod (1000000000+7)
#define middle (l+r)>>1
#define SIZE 10000000+10
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double lb;
const int inf_max = 0x3f3f3f3f;
const ll Linf = 9e18;
const int maxn = 100+10;
const long double nature = 2.7182818;
const double eps=0.0001;
using namespace std;
int mp[maxn][maxn],n,ans,dp[1<<20][20+10];
//dp[i][j]表示从0到j,用了的点的集合的十进制是i时 所得到的最小价值
int main()
{
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                cin>>mp[i][j];    //读入图
        memset(dp,inf_max,sizeof(dp));
        dp[1][0]=0;  //初始状态只有第0个点用了,所以只有第0位为1,十进制也就是1
        for(int i=0;i< (1 << n);i++)
            for(int j=0;j<n;j++)
                if((i >> j) & 1) //判断i的第j位是不是1,因为我们是枚举1到1<<n的所有十进制数,所以里面肯定有第j位不是1的,那么这个状态就不合法,就无法更新
                    for(int k=0;k<n;k++)
                        if(((i - (1<<j)) >> k ) & 1)  //同理,j从k走过来,那么j的状态也应该由k的合法状态更新过来
                            dp[i][j]=min(dp[i-(1 << j)][k]+mp[k][j],dp[i][j]);
        printf("%d\n",dp[(1<<n)-1][n-1]);
    }
    return 0;
}


发布了33 篇原创文章 · 获赞 14 · 访问量 421

猜你喜欢

转载自blog.csdn.net/qq_44077455/article/details/103570290
今日推荐