#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" is "<<x<<endl
using namespace std;
const int N = 25;
const int INF = 0x3f3f3f3f;
int dist[N][N];
int dp[N][1<<21];
int main(){
int n;
cin>>n;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
cin>>dist[i][j];
for(int i = 0;i < n;i++)
for(int j = 0; j < (1<<n);j++)
dp[i][j] = INF;
for(int i = 0;i < n;i++)dp[i][0] = dist[i][0];
for(int s = 1;s < (1<<n);s++){
for(int i = 0;i < n;i++){
if((1<<i)&s)continue;
for(int j = 0;j < n;j++)
if((1<<j)&s){
dp[i][s] = min(dp[i][s],dp[j][s - (1<<j)] + dist[i][j]);
}
}
}
cout<<dp[0][(1<<n) - 2]<<endl;
return 0;
}
Uva 10817校长的烦恼
这题主要在于压缩状态空间,然后记忆化搜索
#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
const int N = 125;
typedef long long ll;
const int INF = 1000000000;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){
ll ans = 1;
while(b){
if(b&1)ans = (ans * a)%mod;
a = (a * a)%mod;
b>>=1;
}
return (ans%mod);
}
typedef pair<int,int> pii;
ll s,m,n;
ll c[N],sj[N],dp[N][1<<8][1<<8];
ll solve(int i,int s0,int s1,int s2){
if(i == m + n){
return s2 == (1<<s) - 1?0:INF;
}
ll &ans = dp[i][s1][s2];
if(ans >= 0)
return ans;
ans = INF;
if(i >= m)ans = solve(i + 1,s0,s1,s2);
int m0 = sj[i] & s0,m1 = sj[i] & s1;
s0 ^= m0,s1 = (s1 ^ m1)|m0,s2 |= m1;
ans = min(ans,c[i] + solve(i + 1,s0,s1,s2));
return ans;
}
int main(){
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
#if DBG
freopen("input.txt","r",stdin);
#endif
string line;
while(getline(cin,line)){
stringstream ss(line);
ss>>s>>m>>n;
if(s == 0)break;
for(int i = 0;i < m + n;i++){
getline(cin,line);
stringstream ss(line);
ss>>c[i];
//debug(c[i]);
int x;
sj[i] = 0;
while(ss>>x)sj[i] |= (1<<(x - 1));
//debug(sj[i]);
}
memset(dp,-1,sizeof(dp));
cout<<solve(0,(1<<s) - 1,0,0)<<endl;
}
return 0;
}