Codeforces Round #490(Div.3) F

题目大意

  • n个人,每个人有一个lucky number,每个人抽k张卡片。
  • 一个人如果抽到的卡片中有t个lucky number,这个人的价值为h[t]。
  • 求最大的价值和。

解题思路

  • 只需考虑带有lucky number的卡片,因为其他不是某个人的lucky number的卡片不会影响最后的价值。
  • 不同的lucky number是不会相互影响的。因为如果把某个人lucky number放到另一个lucky number不一样的人那里,只会降低最后的总价值。h是升序的。
  • 所以只需考虑有相同lucky number的人群中怎么分配带有他们的lucky number的卡片。而且不用在dp方程中加入lucky number,因为都是一样的,即与lucky number无关。
  • 令dp[x][y]为x个lucky number(记为q)相同的人,分配y张带有q的卡片的最大价值。则\(dp[x+1][y+i]=max\{dp[x][y]+h[i],0<=i<=k\}\),则最后的总价值为\(\mathit{ans} = \sum\limits_{i = 1}^{10^5}\mathit{dp}[f_i][c_i]\)

代码

#include <bits/stdc++.h>
#define REP(i,a,b) for (int i=(a); i<(b); i++)
using namespace std;

const int maxn = 6010;

int n, k;
int card[maxn], fav[510], joy[15];
int dp[520][maxn];
int f[100010], c[100010];

int main()
{
    scanf("%d%d", &n, &k);
    int tot = n * k;
    REP(i, 0, tot) {
        scanf("%d", &card[i]);
        c[card[i]]++;
    }
    REP(i, 0, n) {
        scanf("%d", &fav[i]);
        f[fav[i]]++;
    }
    REP(i, 1, k+1) scanf("%d", &joy[i]);
    REP(x, 0, n) REP(y, 0, tot) REP(i, 0, k+1) {
        dp[x+1][y+i] = max(dp[x+1][y+i], dp[x][y] + joy[i]);
    }
    int ans = 0;
    REP(i, 0, 100010) {
        if (f[i] != 0)
            ans += dp[f[i]][c[i]];
    }
    printf("%d\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/RFisher/p/9222178.html

时间: 2024-07-30 22:07:16

Codeforces Round #490(Div.3) F的相关文章

Codeforces Round #490 (Div. 3) F - Cards and Joy

F - Cards and Joy 思路:比较容易想到dp,直接dp感觉有点难,我们发现对于每一种数字要处理的情况都相同就是有 i 张牌 要给 j 个人分, 那么我们定义dp[ i ][ j ]表示 i 张牌给 j 个人分最大的价值可以得到dp方程如下: dp[ i ][ j ] = max(dp[ i - u ][ j - 1 ] + f[ u ] )   u <= k 暴力转移就好了. #include<bits/stdc++.h> #define LL long long #def

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/contest/988/problem/E Description Polycarp lives on a coordinate line at the point x=0. He goes to his friend that lives at the point x=a. Polycarp can

Codeforces Round #501 (Div. 3) F. Bracket Substring

题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60949 ....看不懂 设dp[i][j][l]表示前i位,左括号-右括号=j,匹配到l了 状态转移,枚举下一个要填的括号,用next数组求状态的l,分别转移 代码 #include<bits/stdc++.h> using namespace std; const int maxn = 207;

Codeforces Round #392 (Div. 2) F. Geometrical Progression

原题地址:http://codeforces.com/contest/758/problem/F F. Geometrical Progression time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output For given n, l and r find the number of distinct geometrical pro

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k. 现在问怎么交换行与行,可以使得最后的这个k最大. 题解: 人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/art

Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\),\(pref_j\),一个人可以买一道菜的条件是 1. \(p_i \leq inc_j \leq s_i\) 2. \(|b_i - pref_j| \leq inc_j-p_i\) ,问每个人分别能买多少道菜 题解 转化一下公式 \(p_i \leq inc_j \leq s_i\) 下面两个满

Codeforces Round #549 (Div. 2) F 数形结合 + 凸包(新坑)

https://codeforces.com/contest/1143/problem/F 题意 有n条形如\(y=x^2+bx+c\)的抛物线,问有多少条抛物线上方没有其他抛物线的交点 题解 \(y=x^2+bx+c=>y+x^2=bx+c\),转换为点\((x,y+x^2)\)在bx+c的直线上 两个点确定一条抛物线,同时也确定了一条直线 需要选择最上面那些点相邻确定的抛物线,所以维护一个上凸包即可 维护上凸包,当前点在前进方向左边需要向后退,cross(a,b)>=0 代码 #inclu

Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)

题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的时间.然后有先手和后手俩个人. ?先手可以这么操作:在规定总时间T到达某个节点然后一定要返回根节点1,期间可以选择吃掉某些节点上的某些饼干(前提是保证剩下的时间能够回到根节点): ?后手可以这么操作:在先手到达的位置和这个位置的孩子之间的连边选择一条让先手吃得更多的边摧毁掉,也可以跳过这个过程: 问

Codeforces Round #615 (Div. 3) F. Three Paths on a Tree

F. Three Paths on a Tree 原题链接:https://codeforces.com/contest/1294/problem/F 题目大意: 给定一棵树,选出三点,使三点连成的j简单路径最大.简而言之,三个点连成的边的集合大小. 解题思路: 假设任取一点为三点连线的公共点,最长路径就是这个点到其他三个点的三条最长边之和,可知这个点一定在直径上(画图分析假设不在时的最长路径可反证).所以先求出树的直径,在使用$ans =(a b+a c+b c) / 2$遍历可以得到第三个点