K K 张牌,牌上有不同的数字,记第ii张牌上的数字为ci"role="presentation"style="position:relative;"> ci c i..." />
当前位置: 代码迷 >> 综合 >> 【CodeForces】【DP】999F-Cards and Joy
  详细解决方案

【CodeForces】【DP】999F-Cards and Joy

热度:29   发布时间:2023-11-21 07:14:44.0

CodeForces 999F Cards ans Joy

题目

◇题目传送门◆

题目大意

NN个人,每人要得到 K 张牌,牌上有不同的数字,记第ii张牌上的数字为 c i 。第ii个人有自己喜欢的数字,记为 f i 。若每个人能够得到ii张自己所喜欢的牌,则能够获得 h i 的快乐值。将每个人所获得的快乐值的总和称为总快乐值,求能获得的最大总快乐值。

思路

非常裸的一道DP题。

我们记f[i][j]f[i][j]为将ii张相同的牌分给 j 个所获得的最大快乐值。

很容易得出状态转移方程:

f[i][j]={ h[min(i,K)](1iN×K)max{ f[i?k][j?1]+h[k]}(1iN×T,2jN,1kmin(i,K))f[i][j]={max{f[i?k][j?1]+h[k]}(1≤i≤N×T,2≤j≤N,1≤k≤min(i,K))h[min(i,K)](1≤i≤N×K)

我们同时记C[i]C[i]为数值为ii的牌的数量, P [ i ] 为喜欢数值为ii的人数,答案即为:

i = 0 M a x n u m f [ C [ i ] ] [ P [ i ] ] ( P [ i ] 0 )

实现细节

注意:可能会炸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 LOACLfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifReadIn();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!

如有不妥之处请在评论中指出,我会尽快回复!