题意:
现在有n个菜,要吃m个菜,每个菜最多吃一次,每个菜有一个满意度,并且现在存在k个规矩,吃完x立即吃y会额外增加满意度,问最大满意度是多少
思路:
很明显的状压dp,dp[i][j]表示,在i的状态下,上次吃的是j的最大满意度,那么对于一个i,我就枚举上一次最后吃的什么和下次吃什么即可
错误及反思:
打得时候没看到立刻吃才有效,找了半天bug
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 600100;
int n,m,k;
long long zy[20][20];
long long arr[20];
long long val[N][20];
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%I64d",&arr[i]);
int tot=1;
for(int i=0;i<n;i++)
tot*=2;
for(int i=0,tempa,tempb;i<k;i++)
{
long long tempc;
scanf("%d%d%I64d",&tempa,&tempb,&tempc);
zy[tempa][tempb]=tempc;
}
memset(val,0,sizeof(val));
for(int i=1;i<tot;i++)
{
for(int j=1;j<=n;j++)
{
if((i>>(j-1))%2)
{
for(int k=1;k<=n;k++)
{
if((i>>(k-1))%2)
{
val[i][j]=max(val[i][j],val[i^(1<<(j-1))][k]+zy[k][j]+arr[j]);
}
}
}
}
}
long long ans=0;
for(int i=0;i<tot;i++)
{
int temp=i;
int num=0;
while(temp)
{
if(temp%2) num++;
temp/=2;
}
if(num==m)
for(int j=1;j<=n;j++)
ans=max(ans,val[i][j]);
}
printf("%I64d\n",ans);
}