题目链接http://codeforces.com/contest/727/problem/F 
题目大意:有n个问题,每个问题有一个价值ai,一开始的心情值为q,每当读到一个问题时,心情值将会加上该问题的价值。问题只能按顺序读。有m个询问,求当q=bi时,至少要删去多少个问题才能使得在任何时候心情值都>=0

参考这篇:http://blog.csdn.net/aufeas/article/details/53031439

解法一: 贪心

分别求出最多删去i个问题需要的初始心情值的最小值f[i],最后在f数组上二分 求解答案。

利用贪心暴力计算f[i], 即如果当前心情小于0,就去掉 价值最小的问题。

时间复杂度感人。。O(n^2*logn*log10^12+m*logn)

我一开始用了set,一直TLE, 改成priority_queue就过了。

代码:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <queue>
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <set>
  7. using namespace std;
  8.  
  9. #define N 800
  10. typedef long long ll;
  11.  
  12. int n,m;
  13. int a[N];
  14. ll b[N];
  15. set<int> st;
  16.  
  17. bool Check(ll lim,int k)
  18. {
  19. priority_queue<int,vector<int>,greater<int> > q;
  20. int cnt=;
  21. for (int i=;i<=n;i++)
  22. {
  23. if (a[i]>=) lim+=a[i];
  24. else
  25. {
  26. q.push(a[i]); lim+=a[i];
  27. if (lim<)
  28. {
  29. lim-=q.top(); cnt++;
  30. q.pop();
  31. if (cnt>k) return false;
  32. }
  33. }
  34. }
  35. return true;
  36. }
  37.  
  38. ll Calc(int k)
  39. {
  40. ll L=,R=1e12,Mid;
  41. while (L<R)
  42. {
  43. Mid=(L+R)>>;
  44. if (Check(Mid,k)) R=Mid;
  45. else L=Mid+;
  46. }
  47. return L;
  48. }
  49.  
  50. int Solve(ll lim)
  51. {
  52. int L=,R=n,Mid;
  53. while (L<R)
  54. {
  55. Mid=(L+R)>>;
  56. if (b[Mid]<=lim) R=Mid;
  57. else L=Mid+;
  58. }
  59. return L;
  60. }
  61.  
  62. int main()
  63. {
  64. //freopen("in.in","r",stdin);
  65. //freopen("out.out","w",stdout);
  66.  
  67. scanf("%d%d",&n,&m);
  68. for (int i=;i<=n;i++) scanf("%d",&a[i]);
  69.  
  70. for (int i=;i<=n;i++) b[i]=Calc(i);
  71.  
  72. ll lim;
  73. for (int i=;i<=m;i++)
  74. {
  75. scanf("%I64d",&lim);
  76. printf("%d\n",Solve(lim));
  77. }
  78.  
  79. return ;
  80. }

解法二: DP

这个dp有点巧妙,是从后往前的顺序。

dp[i][j]表示考虑i-n这些问题,最多只能去掉j个问题, 初始心情至少要多少。   如果求出dp数组,最后只要在dp[1]上二分求答案就好了。

如果a[i]>=0, 那么a[i]这个问题肯定没必要删掉, dp[i][j]=dp[i+1][j]-a[i];

如果a[i]<0 , dp[i][j]=min(dp[i+1][j]-a[i] ,  dp[i+1][j-1]);  分别是删掉a[i]和不删的情况。

如果算出来dp[i][j]<0, 那么dp[i][j]=0.    因为要保证中间过程不会心情有负的情况。

代码:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <queue>
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <set>
  7. using namespace std;
  8.  
  9. #define N 800
  10. typedef long long ll;
  11.  
  12. int n,m;
  13. int a[N];
  14. ll dp[N][N];
  15.  
  16. int Solve(ll lim)
  17. {
  18. int L=,R=n,Mid;
  19. while (L<R)
  20. {
  21. Mid=(L+R)>>;
  22. if (dp[][Mid]<=lim) R=Mid;
  23. else L=Mid+;
  24. }
  25. return L;
  26. }
  27.  
  28. int main()
  29. {
  30. //freopen("in.in","r",stdin);
  31. //freopen("out.out","w",stdout);
  32.  
  33. scanf("%d%d",&n,&m);
  34. for (int i=;i<=n;i++) scanf("%d",&a[i]);
  35.  
  36. for (int i=n;i>=;i--)
  37. {
  38. for (int j=;j<=n-i+;j++)
  39. {
  40. if (a[i]<)
  41. {
  42. if (j) dp[i][j]=min(dp[i+][j]-a[i],dp[i+][j-]);
  43. else dp[i][j]=dp[i+][j]-a[i];
  44. }
  45. else dp[i][j]=dp[i+][j]-a[i];
  46. if (dp[i][j]<) dp[i][j]=;
  47.  
  48. }
  49. }
  50.  
  51. ll lim;
  52. for (int i=;i<=m;i++)
  53. {
  54. scanf("%I64d",&lim);
  55. printf("%d\n",Solve(lim));
  56. }
  57.  
  58. return ;
  59. }

 

codeforces 727F. Polycarp's problems的更多相关文章

  1. Polycarp's problems

    Polycarp's problems time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. Codeforces 659F Polycarp and Hay 并查集

    链接 Codeforces 659F Polycarp and Hay 题意 一个矩阵,减小一些数字的大小使得构成一个连通块的和恰好等于k,要求连通块中至少保持一个不变 思路 将数值从小到大排序,按顺 ...

  3. Codeforces 727 F. Polycarp's problems

    Description 有一个长度为 \(n\) 有正负权值的序列,你一开始有一个值,每次到一个权值就加上,最少需要删掉多少数值才能到序列末尾.\(n \leqslant 750,m \leqslan ...

  4. Codeforces 723C. Polycarp at the Radio 模拟

    C. Polycarp at the Radio time limit per test: 2 seconds memory limit per test: 256 megabytes input: ...

  5. codeforces 723C : Polycarp at the Radio

    Description Polycarp is a music editor at the radio station. He received a playlist for tomorrow, th ...

  6. [Codeforces 864B]Polycarp and Letters

    Description Polycarp loves lowercase letters and dislikes uppercase ones. Once he got a string s con ...

  7. Codeforces 913D - Too Easy Problems

    913D - Too Easy Problems 思路:二分check k 代码: #include<bits/stdc++.h> using namespace std; #define ...

  8. Codeforces 861D - Polycarp's phone book

    861D - Polycarp's phone book 思路:用map做的话,只能出现一次循环,否则会超时. 代码: #include<bits/stdc++.h> using name ...

  9. CodeForces 81D.Polycarp's Picture Gallery 乱搞

    D. Polycarp's Picture Gallery time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

随机推荐

  1. Cocos2d-x 核心概念 - 导演(Director)

    导演类(Director) 用于管理场景对象,采用的是单例模式(单例模式能保存一致的配置信息,方便管理场景对象) 获得导演实例的语句如下 local director = cc.Director:ge ...

  2. android面试题

    1. 请描述一下Activity 生命周期. 答: 如下图所示.共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onP ...

  3. [JS复习] JS 基础知识

    项目结尾,空闲时间,又把<JS 基础知识> 这本书过了一遍,温故知新后,很多知其然不知其所以然的内容 豁然开朗. [1. 用于范围的标签] display  :inline or bloc ...

  4. js float 数据相加,有的正确,有的不对

    转:http://bbs.csdn.net/topics/360259080 //浮点数加法运算function FloatAdd(arg1,arg2){    var r1,r2,m;    try ...

  5. VB.net的特殊语法(区别于C#.NET)

    1:引入命名空间(Imports) Imports System.Exception Imports System.Data.SqlClient Imports System.Security.Cry ...

  6. CentOS6.5 根目录结构划分

    /bin    系统的执行程序文件/dev    硬件设备的文件目录/home    用户的家目录/lib    系统库文件目录/mnt    挂载目录,外设的挂载/media    经常用于媒体文件 ...

  7. J2EE版本

    Different versions of JEE: Note: JPE (Java Professional Edition) project announced in May 1998 at Su ...

  8. angular中ng-repeat ng-if 中的变量的值控制器中为什么取不到

    这个问题的本质是:v-repeat会产生子scope,这时你在控制器里拿值,相当于父scope里面取子scope的值,因为Angular.js中作用域是向上查找的,所以取不到. 操作过程如下: 相关代 ...

  9. 老王讲自制RPC框架.(三.ZOOKEEPER)

    (#)定义Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配 ...

  10. MySQL存储IP地址操作

    数据库数据表创建语法: DROP TABLE IF EXISTS `admin`; CREATE TABLE IF NOT EXISTS `admin`( `adminid` INT UNSIGNED ...