http://codeforces.com/problemset/problem/580/D
状压DP裸题 dp[i][j]代表状态i下 以第j道菜为结尾时的最大满意度 当某一状态恰好有m道菜时更新一下答案即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=20;
const int maxm=1e6+10;
ll dp[maxm][maxn];
ll e[maxn][maxn];
ll val[maxn];
int bit[maxm][maxn];
int pre[maxn],cnt[maxm];
int n,m,p;
void init()
{
int i,j,t;
pre[0]=1;
for(i=1;i<=n;i++){
pre[i]=2*pre[i-1];
}
for(i=0;i<pre[n];i++){
j=0,t=i;
while(t>0){
bit[i][j++]=t%2;
cnt[i]+=t%2;
t/=2;
}
}
}
ll solve()
{
ll res;
int i,j,k;
for(i=0;i<n;i++){
dp[pre[i]][i]=val[i];
}
res=0;
for(i=0;i<pre[n];i++){
for(j=0;j<n;j++){
if(bit[i][j]){
for(k=0;k<n;k++){
if(!bit[i][k]){
dp[i+pre[k]][k]=max(dp[i+pre[k]][k],dp[i][j]+e[j][k]+val[k]);
}
}
}
}
if(cnt[i]==m){
for(j=0;j<n;j++){
res=max(res,dp[i][j]);
}
}
}
return res;
}
int main()
{
ll w;
int i,u,v;
scanf("%d%d%d",&n,&m,&p);
init();
for(i=0;i<n;i++){
scanf("%lld",&val[i]);
}
while(p--){
scanf("%d%d%lld",&u,&v,&w);
u--,v--;
e[u][v]=w;
}
printf("%lld\n",solve());
return 0;
}