题目链接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就过了。

代码:

#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std; #define N 800
typedef long long ll; int n,m;
int a[N];
ll b[N];
set<int> st; bool Check(ll lim,int k)
{
priority_queue<int,vector<int>,greater<int> > q;
int cnt=;
for (int i=;i<=n;i++)
{
if (a[i]>=) lim+=a[i];
else
{
q.push(a[i]); lim+=a[i];
if (lim<)
{
lim-=q.top(); cnt++;
q.pop();
if (cnt>k) return false;
}
}
}
return true;
} ll Calc(int k)
{
ll L=,R=1e12,Mid;
while (L<R)
{
Mid=(L+R)>>;
if (Check(Mid,k)) R=Mid;
else L=Mid+;
}
return L;
} int Solve(ll lim)
{
int L=,R=n,Mid;
while (L<R)
{
Mid=(L+R)>>;
if (b[Mid]<=lim) R=Mid;
else L=Mid+;
}
return L;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]); for (int i=;i<=n;i++) b[i]=Calc(i); ll lim;
for (int i=;i<=m;i++)
{
scanf("%I64d",&lim);
printf("%d\n",Solve(lim));
} return ;
}

解法二: 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.    因为要保证中间过程不会心情有负的情况。

代码:

#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std; #define N 800
typedef long long ll; int n,m;
int a[N];
ll dp[N][N]; int Solve(ll lim)
{
int L=,R=n,Mid;
while (L<R)
{
Mid=(L+R)>>;
if (dp[][Mid]<=lim) R=Mid;
else L=Mid+;
}
return L;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]); for (int i=n;i>=;i--)
{
for (int j=;j<=n-i+;j++)
{
if (a[i]<)
{
if (j) dp[i][j]=min(dp[i+][j]-a[i],dp[i+][j-]);
else dp[i][j]=dp[i+][j]-a[i];
}
else dp[i][j]=dp[i+][j]-a[i];
if (dp[i][j]<) dp[i][j]=; }
} ll lim;
for (int i=;i<=m;i++)
{
scanf("%I64d",&lim);
printf("%d\n",Solve(lim));
} return ;
}

 

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. /usr/include/features.h:367:25:fatal errorXXXXXX类似这种问题

    解决方案: sudo apt-get install g++=multilib //至于为什么还没搞清楚,搞清楚在写上来吧!

  2. Android Studio 基本使用

    一 . 目录结构: 目录结构本身代表了一个workspace空间 Android stuido是单工程的开发模式 Android stuido里面project表示工作空间,相当于eclipse里面的 ...

  3. 组合suan

    /// 求从数组a[1..n]中任选m个元素的所有组合. /// a[1..n]表示候选集,n为候选集大小,n>=m>0. /// b[1..M]用来存储当前组合中的元素(这里存储的是元素 ...

  4. logback 配置详解(二)——appender

    1.appender <appender>是<configuration>的子节点,是负责写日志的组件. <appender>有两个必要属性name和class.n ...

  5. Eclipse 实现关键字自动补全功能

    一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...

  6. jQuery index()

    index() index() 方法返回指定元素相对于其他指定元素的 index 位置. 语法 $(selector1).index(selector2) selector2:可选,指定元素:为空时默 ...

  7. 常见电子元器件检测方法。——Arvin

    电子设备中使用着大量各种类型的电子元器件,设备发生故障大多是由于电子元器件失效或损坏引起的.因此怎么正确检测电子元器件就显得尤其重要,这也是电子维修人员必须掌握的技能.我在电器维修中积累了部分常见电子 ...

  8. windows下安装python模块

    如何在windows下安装python模块 1. 官网下载安装包,比如(pip : https://pypi.python.org/pypi/pip#downloads) pip-9.0.1.tar. ...

  9. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  10. Oracle分页查询=======之伪列的使用

    ========伪列========== 在Oracle数据库中,伪列不存在表中,但是可以从表中查询到 例如:SELECT ROWID 伪列,tname 教师姓名 FROM teacher; ==== ...