zoukankan      html  css  js  c++  java
  • Cards and Joy (dp好题)

    Cards and Joy

     CodeForces - 999F 

    There are nn players sitting at the card table. Each player has a favorite number. The favorite number of the j-th player is fj

    There are knk⋅n cards on the table. Each card contains a single integer: the i-th card contains number ci. Also, you are given a sequence h1,h2,,hk Its meaning will be explained below.

    The players have to distribute all the cards in such a way that each of them will hold exactly kk cards. After all the cards are distributed, each player counts the number of cards he has that contains his favorite number. The joy level of a player equals htht if the player holds tt cards containing his favorite number. If a player gets no cards with his favorite number (i.e.t=0), his joy level is 0.

    Print the maximum possible total joy levels of the players after the cards are distributed. Note that the sequence h1,…,hk is the same for all the players.

    Input

    The first line of input contains two integers n and k (1n500,1k10) — the number of players and the number of cards each player will get.

    The second line contains kn integers c1,c2,,ckn (1ci105) — the numbers written on the cards.

    The third line contains nn integers f1,f2,,fn (1fj105) — the favorite numbers of the players.

    The fourth line contains kk integers h1,h2,,hk (1ht105), where htht is the joy level of a player if he gets exactly tt cards with his favorite number written on them. It is guaranteed that the condition ht1<h holds for each t[2..k].

    Output

    Print one integer — the maximum possible total joy levels of the players among all possible card distributions.

    Examples

    Input
    4 3
    1 3 2 8 5 5 8 2 2 8 5 2
    1 2 2 5
    2 6 7
    Output
    21
    Input
    3 3
    9 9 9 9 9 9 9 9 9
    1 2 3
    1 2 3
    Output
    0

    Note

    In the first example, one possible optimal card distribution is the following:

    • Player 1 gets cards with numbers [1,3,8]
    • Player 2 gets cards with numbers [2,2,8]
    • Player 3 gets cards with numbers [2,2,8]
    • Player 4 gets cards with numbers [5,5,5]

    Thus, the answer is 2+6+6+7=212+6+6+7=21.

    In the second example, no player can get a card with his favorite number. Thus, the answer is 0.

    题意:

      有n个人以及 n * k 张牌,每个人分到 k 张牌。每张牌上都有一个数字,每个人都有一个喜爱的数字。若一个人的牌共有 i 个此人喜爱的数字,则此人的快乐值为h[i], h[0] = 0。求如何分配使得所有人的快乐值的和最大,输出该最大值。(其中 1 <= n <= 500, 1 <= k <= 10, 1 <= 牌上的数字, 人喜爱的数字 <= 1e5)
    题解:

      我们先统计出来某个数出现的个数,以及该数字有几个人同时喜欢,比如上面的样例1中,2有4个,并且有2个人喜欢,下面就变成了求怎么分配这4个2可以达到最大快乐值的问题了。很容易想到用DP。

      dp[i]表示当该数字有i个时可以达到的最大快乐值。状态转移方程为dp[i]=max(dp[i],dp[i-l]+h[l])。l从1到k,需要控制i-l>=0,对于数字2来说,第一层for循环遍历有几个人喜欢2,dp[4]=max(dp[4],dp[3]+h[1]) 

      dp[4]=max(dp[4],dp[2]+h[2]),dp[4]=max(dp[4],dp[1]+h[3])  。dp[3]=max(dp[3],dp[2]+h[1])……这是对于如果喜欢这个数字的人只有一个来说的,如果有多个人喜欢该数字,第一层for循环会遍历到。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=1e5+10;
     7 int c[maxn],f[maxn],h[maxn],cnt[maxn],dp[maxn];
     8 int n,t;
     9 int main()
    10 {
    11     int x;
    12     scanf("%d%d",&n,&t);
    13     for(int i=0;i<n*t;i++)
    14     {
    15         scanf("%d",&x);
    16         c[x]++;
    17     }
    18     
    19     for(int i=1;i<=n;i++)
    20     {
    21         scanf("%d",&x);
    22         f[x]++;
    23     }
    24     for(int i=1;i<=t;i++)
    25     {
    26         scanf("%d",&h[i]);
    27     }
    28     long long sum=0;
    29     for(int i=1;i<maxn;i++)
    30     {
    31         if(f[i])//如果有人喜欢这个数字 
    32         {
    33         memset(dp,0,sizeof(dp));
    34             for(int j=1;j<=f[i];j++)//喜欢这个数字的人数 
    35             {
    36                 for(int k=c[i];k>=1;k--)
    37                 {
    38                     for(int l=1;k-l>=0&&l<=t;l++)
    39                     {
    40                         dp[k]=max(dp[k],dp[k-l]+h[l]);
    41                     } 
    42                 }
    43             }
    44             sum+=dp[c[i]];
    45         }
    46         
    47     }
    48     printf("%lld
    ",sum);
    49     
    50 }
  • 相关阅读:
    crontab 启动supervisor爬虫
    frida初体验
    Protobuf 的数据反解析
    adb
    突破SSL Pinning抓app的数据包
    Charles下载与配置
    替换小技巧
    docker 使用
    pandas读取excel
    docker 安装
  • 原文地址:https://www.cnblogs.com/1013star/p/9931410.html
Copyright © 2011-2022 走看看