UVALive 4731 dp+贪心

这个题首先要利用题目的特性,先贪心,否则无法进行DP

因为求期望的话,越后面的乘的越大,所以为了得到最小值,应该把概率值降序排序,把大的数跟小的系数相乘

然后这种dp的特性就是转移的时候,由 i推到i+1每次添加一个数,就要考虑这个新数应该和谁放在一组,枚举他放在哪一组即可

dp[i][j]代表当前第i个数有j个分组时候的最小值

dp[i][j]=dp[k][j-1]+i(prefix[i]-prefix[k-1]),k代表枚举第几个数开始和当前新添加的数为一组,prefix为前缀和,为了迅速得出区间和

注意边界处理和一些细节

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#define LL __int64
using namespace std;
struct node
{
    int x,y;
    bool operator < (const node&rhs) const
    {
        if (x==rhs.x) return y<rhs.y;
        return x<rhs.x;
    }
}tasks[100010];
bool cmp(node a,node b)
{
    if (a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
int n,m;
multiset<node> v;
multiset<node>::iterator it;
/*
int bs(int p,int q)
{
    int L=0,R=v[p].size(),mid;
    while (L<R)
    {
        mid=(L+R)>>1;
        if (v[p][mid]<tasks[q].x) L=mid+1;
        else R=mid;
    }
    return L;
}
*/
int main()
{
    int a,b;
    while (scanf("%d%d",&m,&n)!=EOF)
    {
        int maxn=0;
        v.clear();
        for (int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            v.insert((node){a,b});
            maxn=max(b,maxn);
        }
        for (int i=1;i<=n;i++){
            scanf("%d%d",&a,&b);
            tasks[i].x=a;
            tasks[i].y=b;
        }
        sort(tasks+1,tasks+1+n);
        //for (int i=0;i<=maxn;i++) sort(v[i].begin(),v[i].end());
        LL ans=0;
        int sum=0;
        for (int i=n;i>=1;i--){
            it=v.lower_bound(tasks[i]);
                if (it==v.end()) continue;
                else{
                    v.erase(it);
                    ans+=(LL)tasks[i].x*500+(LL)tasks[i].y*2;
                    sum++;

                }
        }
        printf("%d %I64d\n",sum,ans);
    }
    return 0;
}

  

UVALive 4731 dp+贪心

时间: 2024-08-13 02:31:53

UVALive 4731 dp+贪心的相关文章

codeforces219C - Color Stripe DP+贪心

题意:给你n,k,大意就是说给你一个已经涂满颜色长为n的字符串,现有k种颜色可以选择,问你最少要改变多少个箱子的颜色使得相邻箱子之间颜色不同. 解题思路:当k = 2 时单独讨论,不能用贪心,其余情况都可贪心得到. 解题代码: 1 // File Name: 219c.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月26日 星期六 15时45分56秒 4 5 #include<vector> 6 #include<list>

ZOJ 2109 FatMouse&#39; Trade (背包 dp + 贪心)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1109 FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J

HDU 5303(Delicious Apples- 环上折半dp+贪心)

Delicious Apples Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submission(s): 1585    Accepted Submission(s): 514 Problem Description There are n apple trees planted along a cyclic road, which is L metres

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l

Codeforces 830A. Office Keys (背包dp+贪心) / (二分+贪心)

题目链接: http://codeforces.com/problemset/problem/830/A 题意: n个人,k个钥匙(n<=k),p表示这些人要到达的位置 给出n个人的位置以及钥匙的位置,问花时间最多的那个人用时最少是多少?? 思路: 二分+贪心: 二分最少时间,需要对a,b位置数组排序,我们check函数只需要从左到右一个一个找过去,因为如果选后边的点,可能会使结果更差,假如当前这个人选后面的点,那可能会选中后面的人可以选的唯一的钥匙,不会使解更优. check(40)的时候答案

HDU 4939 Stupid Tower Defense(dp+贪心)

dp[i][j]表示到了第i步放了j个减速,造成的伤害.我们用贪心的策略把造成一段伤害的放在最后面,造成持续伤害的与减速放在前i个中这样得到的伤害是最高的. 所以前(i,j)中的伤害为dp[i][j] = max(dp[i-1][j]+(j*z+t)*(max(0LL, i-1-j))*y, dp[i-1][j-1]+((j-1)*z+t)*(i-j)*y); 每次造成的伤害就为:dp[i][j]+(n-i)*(j*z+t)*(x+(i-j)*y).然后取一个最大值,就是伤害的最大值了. Stu

UVA 1379 - Pitcher Rotation(DP + 贪心)

题目链接:1379 - Pitcher Rotation 题意:n个人,m个敌人,去比赛,有得分,n个人可以重复比,但是每次比完要休息4天,问最大得分 思路:dp[i][j][k][l][x] 表示第场比赛,前一天为j,两天为k,三天为l,四天为x,的最大得分,然后由于只有每个人5天就能用一次,所以对于每个人来说,只有得分前5的会被使用上,所以后4维状态只需要5^4,进行状态转移,不用比赛的情况分开考虑,还有这题内存有限,要用滚动数组优化不然会RE 代码: #include <stdio.h>