ZZNU 我只看看不写题 贪心?dp?不懂

G : 我只看看不写题

Progress Bar

时间限制:1 Sec 内存限制:128 MiB

提交:221
答案正确:59

题目描述

伴随着科技的发展,我们的生活也越来越多姿多彩,随着手机的普及,各种交友软件也在快速的发展。

小a是个老实人,当然只是自己理解而已,其实小a是个不折不扣的渣男。因为他在有女朋友的同时,还在疯狂的撒网,利用各种交友软件寻求更适合自己的伴侣。

小a女朋友当然不是省油的灯,自然了解小a的本性,所以在每次见面时就会翻看小a的软件记录,来了解小a近期的状况,机智的小a当然会在女朋友来之前就给完全清理干净了。

终于在某次时间紧急的情况下,小a的软件记录并不一定能够完全删除,但是小a知道,自己每个软件记录的火热程度以及最终删除时间(即可以删除的最晚时间,过时将无法删除)。每个软件记录的删除需要一分钟,软件记录的火热程度,正好对应着女朋友的刺激值,小a想知道,在有限的时间内,如何才能够让女朋友的刺激值最小,求出最小值。

输入

第一行一个正整数T。表示样例个数(0<T<10)

每组有两个整数n,m,分别表示一共有n个软件以及女朋友到来的时间(0<n<=10^5,0<m<=10^6)

往下对应着n行,每行有两个正整数e,f分别对应每个软件记录的火热程度和该软件的最终删除时间。(0<e<=10^5,0<f<=10^6)

题目中涉及到的时间全部以分钟为单位。

输出

	输出对女朋友的最小刺激值;结果占一行。

样例输入

复制

2
4 2
20 1
10 1
30 2
40 2
6 2
20 1
10 1
30 2
40 2
50 3
60 3

样例输出

复制

30
100
// copy的代码不很懂

    #include <iostream>
    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <algorithm>

    using namespace std;
    priority_queue <int, vector<int>, greater<int> > Q;// int型降序优先队列

    vector <int> a[1000100];
    int main()
    {
        int T;
        cin >> T;
        while(T--) {
            int n, m;
            cin >> n >> m;

            int e, f, Max = 0;
            long long ans = 0;

            for(int i=1; i<=n; i++) {
                scanf("%d %d",&e, &f);
                if(f > Max) Max = f;
                ans += e;
                a[f].push_back(e);
            }

            int times = 0;
            for(int t=1; t<=m; t++) {
                times ++;

                int len = a[t].size();
                if(0 == len) continue;

                if(len <= times) {
                    times -= len;
                    for(int j=0; j<len; j++) {
                        Q.push( a[t][j] );
                    }
                }
                else {
                    sort(a[t].begin(), a[t].end());

                    for(int k=1; k<=times; k++) {
                        Q.push(a[t][len-k]);
                    }
                    for(int k = times+1; k<=len; k++) {
                        if(a[t][len-k] > Q.top()) {
                            Q.pop();
                            Q.push(a[t][len-k]);
                        }
                        else break;
                    }
                    times = 0;
                }
                a[t].clear();
            }

            for(int t=m+1; t<=Max; t++) {
                 int len = a[t].size();
                if(0 == len) continue;

                if(len <= times) {
                    times -= len;
                    for(int j=0; j<len; j++) {
                        Q.push( a[t][j] );
                    }
                }
                else {
                    sort(a[t].begin(), a[t].end());

                    for(int k=1; k<=times; k++) {
                        Q.push(a[t][len-k]);
                    }
                    for(int k = times+1; k<=len; k++) {
                        if(a[t][len-k] > Q.top()) {
                            Q.pop();
                            Q.push(a[t][len-k]);
                        }
                        else break;
                    }
                    times = 0;
                }
                a[t].clear();
            }

            while(!Q.empty()) {
                ans -= Q.top();
                Q.pop();
            }
            cout << ans << endl;
        }
        return 0;
    }
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<stack>
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<time.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define debug puts("debug")
#define LL unsigned long long
#define pii pair<int,int>
#define eps 1e-10
#define inf 0x3f3f3f3f
LL MOD=1e9+7;

struct node{
    int a,b;
    bool operator<(const node& tmp)const{
        return a<tmp.a;
    }
}P[100010];
bool cmpb(node A,node B){
    return A.b>B.b;
}
priority_queue<node>q;
int main()
{
    LL t,n,m,i,j,k;
    cin>>t;
    while(t--){
        while(!q.empty()) q.pop();
        scanf("%lld%lld",&n,&m);
        LL sum=0,ans=0;
        for(i=1;i<=n;++i){
            scanf("%d%d",&P[i].a,&P[i].b);
            sum+=P[i].a;
        }
        sort(P+1,P+1+n,cmpb);
        for(i=m,j=1;i>=1;--i){
            while(j<=n&&P[j].b>=i)
                q.push(P[j++]);
            if(!q.empty()){
                ans+=q.top().a;
                q.pop();
            }
        }
        cout<<sum-ans<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/9065261.html

时间: 2024-10-10 13:07:31

ZZNU 我只看看不写题 贪心?dp?不懂的相关文章

ZZNU 2095 : 我只看看不写题

把所有时间加起来,最后从大到小排序,一定要把大的先减去.注意花费的时间都是1,这一秒用过就不能再用了,所有用到了并查集的部分知识 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<ctime> u

调试,高级--step into my code ,只调试自己写的代码,shux,各种step操作debug

调试,高级--step into my code ,只调试自己写的代码,shux,各种step操作debug debug调试IDEA step into mycode fram drop 可以扔掉栈帧,从新开始,但是有全局变量观察变化必须重头开始 step out 结束当前方法的调试调到这个方法所在代码行的下一行 step in /force in 可以调试源代码 step over 如果代码片段有方法,跳过方法的执行过程,也就是不调试方法的执行过程 step over 和 step in 联合

贪心+dp

贪心+dp 好多题都是这个思想, 可以说是非常重要了 思想一: 在不确定序列无法dp的情况下, 我们不妨先假设序列已经选定, 而利用贪心使序列达到最优解, 从而先进行贪心排序, 在进行dp选出序列 思想二: 最优解一定满足上一个状态在某 Problem 1 n 座楼房,立于城中. 第 i 座楼,高度 \(h_i\) . 你需要一开始选择一座楼,开始跳楼.在第 座楼准备跳楼需要 的花费.每次可以跳到任何一个还没有跳过的楼上去.但跳楼是有代价的,每次跳到另外一座楼的代价是两座楼高度的差的绝对值,最后

URAL 1203 Scientific Conference(贪心 || DP)

Scientific Conference 之前一直在刷计算几何,邀请赛连计算几何的毛都买见着,暑假这一段时间就做多校,补多校的题目,刷一下一直薄弱的DP.多校如果有计算几何一定要干掉-.- 题意:给你N个报告会的开始时间跟结束时间,问你做多可以听几场报告会.要求报告会之间至少间隔为1. 思路:其实是个活动安排问题,可以用贪心也可以用DP,贪心写起来会比较简单一些,因为练习DP,所以又用DP写了一遍. 贪心的话就是一个很简单的活动选择问题,从结束时间入手,找每次的最优选择. 1 struct n

codeforces349B - Color the Fence 贪心+DP

题意:1-9每个字母需要消耗ai升油漆,问你用油漆最多刻意画多大的数字 解题思路: 首先我们要贪心,可以知道我最优是先使我们位数尽可能长,然后才是就是位数长的情况下使得从最高位开始尽可能大.所以要取满足最长位最小的那个数,方便我们DP 解题代码: 1 // File Name: 349b.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月24日 星期四 21时40分13秒 4 5 #include<vector> 6 #include&

ZOJ 3905 Cake(贪心+dp)

动态规划题:dp[i][j]表示有i个Cake,给了Alice j个,先按照b排序,这样的话,能保证每次都能成功给Alice Cake,因为b从大到小排序,所以Alice选了j个之后,Bob最少选了j个,所以i>=2*j, 并且每次Alice选的时候Bob已经选过了.所以当i>=2 * j的时候Alice一定能选. 所以dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + ary[i].a); dp[i - 1][j]表示Alice不选第i个,dp[i

HDU 4939 Stupid Tower Defense(贪心+dp)

HDU Stupid Tower Defense 题目链接 题意:有一些塔,红塔能攻击经过他的,绿塔能攻击经过之后的,蓝塔能把经过之后的减速,求在1-n上放塔,求伤害最大值 思路:一开始以为直接贪心,绿塔最前,蓝塔中间,红塔最后就可以了,结果其实是错的 不过,红塔放最后是肯定的,这个很显然就不多证明了,是贪心的思想 然后就dp[i][j]表示放到i,前面有j个绿塔去状态转移即可 代码: #include <cstdio> #include <cstring> #include &l

CF459E Pashmak and Graph【贪心+dp】

题目:CF459E Pashmak and Graph 题意:给出n个点,m条边的图,然后让你每次只能向权值更大边走,求最大的边数.可以走多次 分析:由于点比较多,我们可以先对权值从小到大排序,然后从小的开始,更新它的到的节点的值为前一个节点值+1,但是还会出现权值相等成环的情况,所以我们可以对相等的先不更新,保存起来,等相等的结束了再更新. 代码: #include<cstdio> #include<algorithm> using namespace std; const in

先做别人的例子,让自己去理解,比看书效果要好——只看不写,永远都不会

我的学习经验就是多做练习,先做别人的例子,让自己去理解,比看书效果要好,做完例子也理解了以后再看书,效果是非常明显的,而且效率也会提高了. 应该给实践分配95%的时间.只看永远都不会. 其实刚开始学习qt要多仿写别人的例子,然后不明白的地方就查 assistant ,然后就是多跟人交流!!!给你推荐一个博客 http://hi.baidu.com/llxqnh 其实我自己也是,那几本VCL原理书仔细看,但是感觉死记硬背没有连贯性,还无法真正理解,更谈不上提出和解决书上没有提到的问题.但是通过自己