codeforces 580D . Kefa and Dishes 状压dp
令dp[i][j]表示状态i中最后一个拿的是j的情况, 然后转移就好。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; int val[20], m, g[20][20]; ll dp[1<<18][18]; int main() { int n, k, x, y, z; cin>>n>>m>>k; for(int i = 0; i<n; i++) { scanf("%d", &val[i]); } for(int i = 0; i<k; i++) { scanf("%d%d%d", &x, &y, &z); g[x-1][y-1] = z; } mem1(dp); for(int i = 0; i<n; i++) { dp[1<<i][i] = val[i]; } ll ans = 0; for(int i = 0; i<(1<<n); i++) { int cnt = 0, flag = 0; for(int j = 0; j<n; j++) if(1<<j&i) cnt++; if(cnt == m) flag = 1; for(int j = 0; j<n; j++) { if(dp[i][j]==-1) continue; if(flag) ans = max(ans, dp[i][j]); for(int k = 0; k<n; k++) { if(1<<k&i) continue; dp[i|1<<k][k] = max(dp[i][j]+val[k]+g[j][k], dp[i|1<<k][k]); } } } cout<<ans<<endl; return 0; }