题目:
思路:
贪心角度出发,牌 i 肯定全部都要发给 喜欢 牌 i 的 人;
那么题目就转换为了 i 个人 拿 k 张喜欢的牌的最大值求和问题.
dp[i][j] 表示 i 个人 拿了 j 张牌的 最大值. 转移 : dp[i][j] = max(dp[i-1][j-l]+h[l]);
Ac_Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#define fir first
#define sec second
using namespace std;
const int maxn = 1e5+7;
int n,k;
int vis[maxn];
int f[maxn];
int h[15];
long long dp[550][5100];
int main() {
scanf("%d%d",&n,&k);
for(int i=0;i<n*k;i++) {
int a;
scanf("%d",&a);
vis[a]++;
}
for(int i=0;i<n;i++) {
int a;
scanf("%d",&a);
f[a]++;
}
for(int i=1;i<=k;i++) {
scanf("%d",&h[i]);
}
for(int i=1;i<=n;i++) {
for(int j=0;j<=(i-1)*k;j++) {
for(int l = 0;l<=k;l++) {
dp[i][j+l] = max(dp[i][j+l],dp[i-1][j] + h[l]);
}
}
}
long long ans =0;
for(int i=1;i<maxn;i++) {
if(f[i] == 0) continue;
ans += dp[f[i]][min(vis[i],f[i]*k)];
}
printf("%lld\n",ans);
return 0;
}