CodeForces 999F Cards ans Joy
题目
题目大意
有 个人,每人要得到 张牌,牌上有不同的数字,记第 张牌上的数字为 。第 个人有自己喜欢的数字,记为 。若每个人能够得到 张自己所喜欢的牌,则能够获得 的快乐值。将每个人所获得的快乐值的总和称为总快乐值,求能获得的最大总快乐值。
思路
非常裸的一道DP题。
我们记 为将 张相同的牌分给 个所获得的最大快乐值。
很容易得出状态转移方程:
我们同时记 为数值为 的牌的数量, 为喜欢数值为 的人数,答案即为:
实现细节
注意:可能会炸int
,请使用long long
。
正解代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int Maxn=500,Maxk=10,Maxnum=1e5;
int N,K;
int cad[Maxn*Maxk+5],peo[Maxn+5],H[Maxk+5];
int C[Maxnum+5],P[Maxnum+5];
int dp[Maxn*Maxk+5][Maxn+5];
void ReadIn() {
scanf("%d %d",&N,&K);
for(int i=1;i<=N*K;i++) {
scanf("%d",&cad[i]);
C[cad[i]]++;
}
for(int i=1;i<=N;i++) {
scanf("%d",&peo[i]);
P[peo[i]]++;
}
for(int i=1;i<=K;i++)
scanf("%d",&H[i]);
}
long long GetAns() {
long long ret=0;
for(int i=0;i<=Maxnum;i++)
if(P[i])ret+=dp[C[i]][P[i]];
return ret;
}
int main() {
#ifdef LOACL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ReadIn();
for(int i=1;i<=N*K;i++) {
dp[i][1]=H[min(i,K)];
for(int j=2;j<=N;j++)
for(int k=1;k<=min(i,K);k++)
dp[i][j]=max(dp[i][j],dp[i-k][j-1]+H[k]);
}
printf("%d\n",GetAns());
return 0;
}
Thanks For Reading!
如有不妥之处请在评论中指出,我会尽快回复!