zoukankan      html  css  js  c++  java
  • Codeforces 999F Cards and Joy 【dp】【性质】

     读完这道题后应该想到牌有多少张都是什么不重要,重要的是player的favorite number是怎么分配的。(因为不是任何player的favorite number不能带来任何joy)然后每个favorite number带来的joy互相不受影响,因为如果favorite number不一样,对应的player肯定不一样。因此我们可以计算每个【favorite number带来的贡献】。

    因此想到dp[i][j]代表i个人分j个favorite number的最大joy(favorite number具体是多少其实不重要),

    转移方程 dp[i][j] = dp[i-1][j-c] + h[c]   枚举第i个人拿c张牌// c = 0 - min(j,k) 【因为一个人最多拿k张牌】,代价为k

    所以整体复杂度是n* (n*k) * k ==> O(n^2 * k^2)。能过

    然后这道题我用递归和递推都写了一遍,两个速度差不多。递推并不能保证比递归快,关键还是看状态数

    再补充一下转移代价与时间复杂度之间为什么是相乘的关系,我以前一直没想清楚:

    实际上是这一层的状态得到要考虑上一层的j个状态,然后这一层的每个状态都要考虑到上一层的j个状态,上一层的状态被重复考虑了。这就是为什么【简单运用】的话线段树能优化dp,因为能区间max,但实际上很复杂,听说要涉及凸包orz

     1 #include<iostream>
     2 #include<map>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 
     7 //只需要考虑每个number带来的贡献,不是任何人favorite number的数没有贡献 
     8 int a[5005],h[15],favorite[505];//favorite[i]为第i个player的favorite number
     9 int vis[100005],ans;
    10 map<int,int> m1,m2;
    11 
    12 int dp[505][5005];// dp[i][j]为i个人分j个favorite number的最大joy 
    13 
    14 int main(){
    15     int n,k; cin>>n>>k;
    16     for(int i=1;i<=n*k;i++) {
    17         cin>>a[i];
    18         m1[ a[i] ] ++;//这个number一共有多少个 
    19     }
    20     for(int i=1;i<=n;i++){
    21         cin>>favorite[i];
    22         m2[ favorite[i] ]++;//这个number是多少人的favorite 
    23     }
    24     for(int i=1;i<=k;i++) cin>>h[i];
    25     
    26     for(int i=1;i<=n;i++){
    27         for(int j=0;j<=i*k;j++){
    28             for(int c=0;c<=min(j,k);c++) dp[i][j] = max( dp[i][j],dp[i-1][j-c]+h[c] );//第i个人分c个favorite number 
    29         }
    30     }
    31     
    32     for(int i=1;i<=n;i++){
    33         if( vis[ favorite[i] ] ) continue;
    34         ans+=dp[ m2[favorite[i]] ][ min( m2[favorite[i]]*k, m1[ favorite[i]]  ) ];
    35         vis[ favorite[i] ] = 1;
    36     }
    37     
    38     cout<<ans;
    39     
    40     return 0;
    41 }
  • 相关阅读:
    浏览器内置对象及其方法
    Leetcode | Path Sum I && II
    Leetcode | 3Sum
    算法分析之渐近符号
    Leetcode | Two Sum
    Leetcode | Wildcard Matching
    LeetCode | Regular Expression Matching
    Leetcode | Subsets I & II
    Leetcode | Populating Next Right Pointers in Each Node I & II
    爱是恒久忍耐,又有恩慈
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9226458.html
Copyright © 2011-2022 走看看