zoukankan      html  css  js  c++  java
  • CF999F Solution

    题目链接

    题解

    可以发现,对于每个人来说,除了他最喜欢的数字以外,分配到的其他数字都不重要。因此本题的重点便是如何将若干个同样数字的卡牌分配到喜欢该数字的人,使愉悦值最大,显然可以用dp解决。

    状态:(dp[i][j]):前(i)个人取了(j)张牌时的最大愉悦值。

    转移方程:(dp[i][j]=max(dp[i-1][j-t]+h[t])quad1le tle j)

    上述方程的时间复杂度为(O(n^2k^2)),可以通过。

    此外,因为无论是什么数字的卡牌,获得愉悦值的规则都是相同的,所以可以共用一个(dp)数组。易得对于数字(m)来说,设(m)出现的次数(i),喜欢(m)的人数为(j),可获得的愉悦值为(dp[i][j])

    AC代码

    #include<bits/stdc++.h>
    const int N=510,K=15,C=1e5+10;
    int c[N*K],f[N],h[K];
    int sumc[C],sumf[C],dp[N][N*K];//dp[i][j]:前i个人取了j张牌时的最大愉悦值。
    using namespace std;
    int main()
    {
    	int n,k,maxn=0,ans=0;
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n*k;i++) 
    	{
    		scanf("%d",&c[i]); 
    		sumc[c[i]]++; maxn=max(maxn,c[i]);
    	}
    	for(int i=1;i<=n;i++) {scanf("%d",&f[i]); sumf[f[i]]++;}
    	for(int i=1;i<=k;i++) scanf("%d",&h[i]);
        //计算dp数组
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n*k;j++)
    			for(int p=1;p<=min(j,k);p++) dp[i][j]=max(dp[i][j],dp[i-1][j-p]+h[p]);
    	//统计答案
        for(int i=1;i<=maxn;i++) ans+=dp[sumf[i]][sumc[i]];
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    接口型模式
    spring-cloud-config安全问题
    适配器模式
    spring boot + quartz 集群
    LeetCode Weekly Contest 147
    LeetCode Weekly Contest 146
    LeetCode Weekly Contest 144
    LeetCode Weekly Contest 143
    LeetCode Weekly Contest 142
    LeetCode Weekly Contest 141
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14227250.html
Copyright © 2011-2022 走看看