CF2041C
题目传送门
Duel 时跳到这题还是比对手慢了四分钟,我已急哭
朴素 dp 很难去重,又
设
int j2 = j - (1 << (l - 1)),k2 = k - (1 << (m - 1));
dp[i][j][k] = min(dp[i][j][k],dp[i - 1][j2][k2] + a[i][l][m]);
但是因为前
那么复杂度理应是
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
#define lowbit(x) x&(-x)
using namespace std;
int n,a[55][55][55],dp[13][4098][4098],ans;
signed main()
{
cin >> n;
memset(dp,0x3f,sizeof(dp));
dp[0][0][0] = 0;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= n;j ++)
for(int k = 1;k <= n;k ++)cin >> a[i][j][k];
}
for(int i = 1;i <= n;i ++)
{
for(int j = 0;j < (1 << n);j ++)
{
if(__builtin_popcount(j) != i)continue ;//可以算某个数二进制位中1的个数
for(int k = 0;k < (1 << n);k ++)
{
if(__builtin_popcount(k) != i)continue ;
for(int l = 1;l <= n;l ++)
{
if((j >> (l - 1)) % 2 == 0)continue ;
for(int m = 1;m <= n;m ++)
{
if((k >> (m - 1)) % 2 == 0)continue ;
int j2 = j - (1 << (l - 1)),k2 = k - (1 << (m - 1));
dp[i][j][k] = min(dp[i][j][k],dp[i - 1][j2][k2] + a[i][l][m]);//状态转移
}
}
}
}
}
cout << dp[n][(1 << n) - 1][(1 << n) - 1];
}