• 999F Cards and Joy


    传送门

    题目大意

    有n个人n*m张牌,每个人分m张牌。每个人有一个自己喜欢的数值,如果他的牌中有x张数值等于这个值则他的高兴度为L[x],求怎样分配牌可以使得所有人的总高兴度最大。

    分析

    我们发现每一个人只有他喜欢的值对他有影响。所以我们统计出喜欢值x的人有多少和有多少值为x的牌,对于每一个x设dp[i][j]表示考虑了喜欢x的人中的前i个给他们分配j张值为x的牌的最大高兴度。最后的答案就是所有不同x的最终dp值的和。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int a[10000],sum,L[10000],apr[100100],tot[10000],dp[502][5002],v[510];
    int main(){
          int n,m,i,j,k;
          scanf("%d%d",&n,&m);
          for(i=1;i<=n*m;i++)
            scanf("%d",&a[i]);
          for(i=1;i<=n;i++){
              int x;
              scanf("%d",&x);
              if(!apr[x]){
                sum++;
                apr[x]=sum;
              }
              v[apr[x]]++;
          }
          for(i=1;i<=m;i++)
            scanf("%d",&L[i]);
          for(i=1;i<=n*m;i++)
            if(apr[a[i]])
              tot[apr[a[i]]]++;
          int ans=0;
          for(int _=1;_<=sum;_++){
              memset(dp,-0x3f,sizeof(dp));
              dp[0][0]=0;
              int t=v[_];
              for(i=1;i<=t;i++)
                for(j=0;j<=min(tot[_],i*m);j++)
                  for(k=0;k<=min(j,m);k++)
                    dp[i][j]=max(dp[i][j],dp[i-1][j-k]+L[k]);
              ans+=dp[t][min(tot[_],t*m)];
          }
          printf("%d
    ",ans);
          return 0;
    }
  • 相关阅读:
    后向边
    图的割点、桥和双连通分支的基本概念
    Hihocoder 1062 最近公共祖先1
    会场问题 差分解法
    POJ2976 01分数规划 普通题
    Hihocoder 1049
    hihocoder 1050树中最长路
    Hihocoder 1055
    POJ1463
    C语言|博课作业02
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9485559.html
Copyright © 2020-2023  润新知