n
n
n个食物中选择
m
m
m个,使得获得的满意度最大。先吃
a
a
a食物再吃
b
b
b食物可以获得额外的满意度。
问最后你能获得的最大满意度是多少。
思路
d
p
[
s
]
[
j
]
dp[s][j]
dp[s][j]表示在状态
s
s
s下,最后吃的是食物
j
j
j获得的最大满意度。
转移方程
d
p
[
s
]
[
j
]
=
m
a
x
(
d
p
[
s
∣
(
1
<
<
j
)
]
[
i
]
+
m
p
[
i
]
[
j
]
+
w
[
j
]
)
dp[s][j]=max(dp[s|(1<<j)][i]+mp[i][j]+w[j])
dp[s][j]=max(dp[s∣(1<<j)][i]+mp[i][j]+w[j]) 表示的是从先吃了食物
i
i
i,还没吃食物
j
j
j的状态转移到最后吃了食物
j
j
j的状态。
注意一下还要用个变量纪录吃了多少个食物。
#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;constint maxn =1e6+5;constint N =27;constint mod =19930726;int n,m,k;int mp[N][N],w[N];
ll dp[1<<18|5][19];intmain(){scanf("%d%d%d",&n,&m,&k);for(int i =0; i < n; i++){scanf("%d",&w[i]);}for(int i =1; i <= k; i++){int a,b;scanf("%d%d",&a,&b);scanf("%d",&mp[a][b]);}int sz =1<<n;
ll ans =0;for(int s =0; s < sz; s++){int cnt =0;for(int i =0; i < n; i++){if(s&(1<<i)){
cnt++;for(int j =0; j < n; j++){if(s&(1<<j))
dp[s][j]=max(dp[s][j],dp[s^(1<<j)][i]+mp[i+1][j+1]+w[j]);}}}if(cnt == m)for(int j =0; j < n; j++) ans =max(ans,dp[s][j]);}printf("%lld\n",ans);}