题意:有n种菜(每一种菜有一个满意值ai>=0),你准备吃m种,每种一次。但是如果你按某种规则吃两种菜的话会增加额外的满意值,比如规则(xi yi ci)就是你先吃第xi个菜,然后马上吃第yi个菜,那么你就会额外增加ci点满意值。有k个这样的规则,问你吃m种菜后的最大满意值是多少。
dp[st][i] 代表在 st状态下,种第i棵菜 然后状态转移 如果在st状态下,已经种了j,那么可以选择把ij种一起,那么转移方程就是 种不中一起 dp[i][j]=max(dp[i][j],dp[st ^ (1<<i)+a[i]+com[i][j])
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int com[1010][1010];
ll dp[(1<<18)+10][20];
int a[10101];
int n;
int Cnt(int x)
{
int cn=0;
for(int i=0;i<n;i++)
{
if(x&(1<<i)) cn++;
}
return cn;
}
int main()
{
int m,k;
cin>>n>>m>>k;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<k;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
x--,y--;
com[x][y]=c;
}
int end=1<<n;
ll ans=0;
memset(dp,0,sizeof(dp));
for(int st=0;st<end;st++)
{
for(int i=0;i<n;i++)
{
if(st&(1<<i))
{
dp[st][i]=a[i];
for(int j=0;j<n;j++)
{
if(i!=j&&(st&(1<<j)))
{
dp[st][i]=max(dp[st][i],dp[st^(1<<i)][j]+a[i]+com[i][j]);
}
}
}
if(Cnt(st)==m)
{
ans=max(ans,dp[st][i]);
}
}
}
cout<<ans<<endl;
return 0;
}