题意:
有N个任务,对于每个任务给出N个花费,第 i 个花费指 这个任务执行之前已经完成了 i 任务的花费,求完成所有任务的最小花费。
思路:
N <= 14
直接状压吧
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
/*
题意:
给出m个数,然后取n位数,保证相邻两个数的差值小于等于2,问有多少种这样的数;
思路:
题意:
有N个任务,对于每个任务给出N个花费,第 i 个花费指 这个任务执行之前已经完成了 i 任务的花费,求完成所有任务的最小花费。
思路:
N <= 14 这难道不是爆搜么?????
2^14 = 1024 * 16*100;
1024 * 1600;
*/
const int INF = 0x3f3f3f3f;
const int N = 15;
int val[N][N];
int n, ans;
bool vis[N];
int dp[(1<<15)];
// 11111111111111 = 2^14 - 1
int solve(){
int temp = (1<<n);
memset(dp, INF, sizeof(dp));
dp[0] = 0;
for(int i=0;i<temp;i++){
memset(vis, false, sizeof(vis));
for(int j = 0;j < n;j++)
if(i & (1<<j)) vis[j] = true;
for(int j = 0;j < n;j++){
if(vis[j]) continue;
int sum = 0;
for(int k = 0;k < n;k++)
if(vis[k] || k == j) sum = sum + val[j][k];
dp[i | (1<<j)] = min(dp[i | (1<<j)], dp[i] + sum);
}
}
return dp[temp - 1];
}
int main(){
int T, cas = 1;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) scanf("%d", &val[i][j]);
int ans;
ans = solve();
printf("Case %d: %d\n",cas++, ans);
}
return 0;
}
/*
100
2
10 10
9000 10
12
14 23 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
0 14 0 14 23 0 14 23 0 14 23 0
*/