2018.07.18 洛谷P1171 售货员的难题(状压dp)

传送门
感觉是一道经典的状压dp,随便写了一发卡了卡常数开了个 O2 O ( 2 ) 优化水过。。。
我直接用 dp[i][j] d p [ i ] [ j ] 表示当前在第i个点,现在点的选取状况是j(二进制表示状态)。
这样的话直接位运算枚举出可以前去的点,然后转移状态。边界是所有点都被取过一遍。
代码如下:

#include
using namespace std;
int dp[21][1050000],dis[25][25],n;
inline int min(int a,int b){return aint dfs(int p,int state){
    if(dp[p][state]!=0x3f3f3f3f)return dp[p][state];
    if(state==(1<1)return dp[p][state]=dis[p][1];
    for(int i=1;i<=n;++i)if(((1<<(i-1))&state)==0)dp[p][state]=min(dp[p][state],dis[p][i]+dfs(i,state|(1<<(i-1))));
    return dp[p][state];
}
int main(){
    memset(dp,0x3f,sizeof(dp));
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            scanf("%d",&dis[i][j]);
    printf("%d",dfs(1,1));
    return 0;
}

你可能感兴趣的:(#,状压dp)