[省赛训练(DP)]Course Selection System

题面:

There are n courses in the course selection system of Marjar University. The i-th course is described by two values: happiness Hi and credit Ci. If a student selects m courses x1, x2, ..., xm, then his comfort level of the semester can be defined as follows:

Edward, a student in Marjar University, wants to select some courses (also he can select no courses, then his comfort level is 0) to maximize his comfort level. Can you help him?

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains a integer n (1 ≤ n ≤ 500) -- the number of cources.

Each of the next n lines contains two integers Hi and Ci (1 ≤ Hi ≤ 10000, 1 ≤ Ci ≤ 100).

It is guaranteed that the sum of all n does not exceed 5000.

We kindly remind you that this problem contains large I/O file, so it‘s recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.

Output

For each case, you should output one integer denoting the maximum comfort.

Sample Input

2
3
10 1
5 1
2 10
2
1 10
2 10

Sample Output

191
0

Hint

For the first case, Edward should select the first and second courses.

For the second case, Edward should select no courses.

这题嘛,刚开始看的时候 隐约觉得是DP,但是细想又不太好写DP的样子

然后一顿胡乱分析……

哦 原来要h大一点会好一点……

所以定义了DP的状态:dp[i][j]表示前i次课j个学分能选到的最大happiness

然后再跑一遍dp数组求这个Comfortable level的最值就好

然后就是 dp[i][j]可以滚动数组 其实就变成0 1 背包的变种了

代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 50050;
long long dp[maxn];
long long h[maxn],c[maxn];
int tot;

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        long long ans = -1;
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            scanf("%lld%lld",h+i,c+i);
            tot += c[i];
        }
        for(int i = 0; i < n; i++){
            for(int j = tot; j >= c[i]; j--)
                dp[j] = max(dp[j], dp[j-c[i]] + h[i]);
        }

        for(int i = 0; i <= tot; i++){
            long long x = dp[i]*dp[i] - dp[i]*i - i*i;
            ans = max(ans,x);
        }
        cout<<ans<<endl;
        memset(dp,0,sizeof(dp));
        tot = 0;
    }
    return 0;
}

qwq这道题 这种丢出一个乱七八糟公式当烟雾弹的题

不要怕难啥的,分析一下实质,简化一下问题,就会比较好写=-=

原文地址:https://www.cnblogs.com/leafsblogowo/p/12639190.html

时间: 2024-08-01 21:38:32

[省赛训练(DP)]Course Selection System的相关文章

ZOJ 3956 Course Selection System 背包DP

ZOJ3956 观察数据范围, c的值非常小 只有100 所以c的和也很有限 只有50000 是否可以从这里下手? 对于某一个c的和 我们一定希望h的和最大 才有可能是最终答案. 于是有了类似背包的dp方程. 代码很简单,就不给出方程了. //比赛的时候想得太多,都想到斜率优化上了,完全忽略了c的范围这么小!!!毕竟图样. //一个人的面命运,当然要靠自我奋斗,但是也要考虑到历史的行程. #include<iostream> #include<cstdio> #include<

2019省赛训练组队赛4.9周二 2017浙江省赛

A - Cooking Competition "Miss Kobayashi's Dragon Maid" is a Japanese manga series written and illustrated by Coolkyoushinja. An anime television series produced by Kyoto Animation aired in Japan between January and April 2017. In episode 8, two

ZOJ3956 ZJU2017校赛(dp)

题意:给出n对(h,c) 记  sumh为选出的h的总和  sumc为选出的c的总和 你可以从中选出任意多对(可以不选) 使得  sumh^2-sumh*sumc-sumc^2 最大 输出最大值 输入第一行表示数据组数 T 接下来一行为n,(1 <= n <= 500) 接下来n行为n对(hi,ci),1 ≤ hi ≤ 10000, 1 ≤ ci≤ 100 保证所有n的总和不超过5000. 分析:H^2-H*C-C^2 从这个式子可以看出,当C固定不动的时候 1)若H>=C,则H越大越好

HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过所需要的花费.现在需要你在树上选择两个点,一个作为买入商品的点,一个作为卖出商品的点,当然需要考虑从买入点到卖出点经过边的花费.使得收益最大.允许买入点和卖出点重合,即收益最小值为0. 解法:我们设1为根节点,假设一开始一个人身上的钱为0.我们设dp[i][0]表示从根节点走到i及其子树并中任一点买

Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries on the string.There are two types of queries:1. Flipping the bits (i.e., changing all 1 to 0 and 0 to 1) between l and r (inclusive).2. Counting the

省赛训练赛(---)

A.HDU4968 最大gpa为从最大区间开始,每次取区间最小分数. 最小gap为从最小区间开始,每次取区间最大分数. #include<bits/stdc++.h> using namespace std; int ave,n; int x[10] = {0,85,80,75,70,60}; double xx[10] = {0,4,3.5,3,2.5,2}; int y[10] = {0,69,74,79,84,100}; double yy[10] = {0,2,2.5,3,3.5,4}

zoj3956(Course Selection System)_Solution

zoj3956_Solution H=sum(hi),C=sum(ci),Value=H*H-H*C-C*C 求Value的最大值 Solution: 动态规划: 共两维:H,C           固定一维C,在该维值C相同的情况下另一维应最大H,从而动态规划另一维H,转变为01背包问题. 优化: H*H-H*C-C*C=0 (H,C>0) H/C=(1+sqrt(5))/2=1.6180- 必会选择h/c>(1+sqrt(5))/2 的(h,c)对 证明: 若Value大于0,则H/C&g

某校赛题(dp + 状态压缩)

题意:一个网格内(5*5)有n个点,问最少多少条线可以把这些点划掉. 题解:以前做过这种类型的题,先把共线点用二进制数表示出来,然后dp的时候传入全1的状态,dp函数内枚举两点消除其他共线点,最后得到最小值,但这道题用这种方法会超时...所以要有新的解法,根据题解.....需要添加两个数组nbits[1 << 20]和first[1 << 20],分别表示存储当前状态有几个1和然后当前状态的第一个0位的位置,dp时有两个参数s和cnt,初始都是0,表示刚开始点都没有被划掉,且线的数

hdu 4028 2011上海赛区网络赛H dp+map离散

一开始用搜索直接超时,看题解会的 1 #include<iostream> 2 #include<cstdio> 3 #include<map> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 #include<algorithm> 9 #include<set> 10 #define inf