裸状压DP ,需要注意的是这题卡常数....2秒时限跑了2.3秒...加了从别人那里看到的优化,竟然时间少了一半..
就是如果在取第i行的数字的时候某个状态是非法的就不进行运算来节省时间...
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int dp[18][1<<18];
int a[20][20];
int main()
{
int t;
cin>>t;
for(int cas=1; cas<=t; cas++)
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
}
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
for(int j=1; j<(1<<n); j++)
{
int cnt=0;
for(int k=0;k<n;k++)
{
if(j&(1<<k))
cnt++;
}
if(cnt!=i) continue;
for(int k=0; k<n; k++)
{
if(j&(1<<k))
dp[i][j]=max(dp[i][j],dp[i-1][j^(1<<k)]+a[i][k+1]);
}
}
}
printf("Case %d: %d\n",cas,dp[n][(1<<n)-1]);
}
return 0;
}