soj 2978 Tasks
来源:互联网 发布:36周胎儿发育情况数据 编辑:程序博客网 时间:2024/05/16 17:08
@(K ACMer)
题意
数组a全部为0,给你一个和数组a同样大小的数组b,你可以选择把任意一个
定义f(a)为a数组中最长的连续0的个数,求f(a)的最小值.
分析:
看起来这个题,要直接求出来最优结果似乎是不可能的,最暴力的枚举是2的指数次的显然不可行.
我们可以二分的来枚举这个最长区间的长度k.然后去判断这个长度是否可以满足要求.
那么如何去判断呢?
想了一下,贪心的去对每个长度为k的区间选取最小值是不对的..
其实这里是一个经典的dp,定义
这里dp的复杂度是
code
#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <map>#include <stack>#include <vector>#include <string>#include <queue>#include <cstdlib>#include <cmath>#include <algorithm>using namespace std;const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 40;int b[maxn], n, t, dp[maxn], que[maxn];bool judge(int x) { int l = 0, r = 0; for (int i = 0; i <= n; i++) { int k = i <= x ? 0 : dp[que[l]]; dp[i] = k + b[i]; if (i - x > que[l]) l++; while (r != l && dp[i] < dp[que[r - 1]]) r--; que[r++] = i; } return dp[n] <= t;}int main(void) { while (~scanf("%d%d", &n, &t)) { for (int i = 0; i < n; i++) scanf("%d", &b[i]); b[n] = 0; int l = 0, r = n; while (r > l) { // cout << l << " " << r << endl; int mid = (r + l) / 2; if (judge(mid)) r = mid; else l = mid + 1; } printf("%d\n", l); } return 0;}
0 0
- soj 2978 Tasks
- soj
- tasks
- soj 1814
- SOJ-1012
- SOJ-1013
- SOJ-1015
- SOJ-1016
- SOJ-3327
- soj 3109
- { }soj.1206
- { }soj.2013
- SOJ-Dollars
- soj 1715
- soj 1681
- soj 6099
- soj 1050
- SOJ 13984
- jquery选取除了div之后 含有类名为a的 标签
- 学习嵌入式Linux-JZ2440-U-Boot简介
- spring的ServletRequestAttributes创建request()得到空指针
- jsp内置对象,及常用方法
- 有趣的小故事
- soj 2978 Tasks
- ActiveMQ学习总结(1)——ActiveMQ快速入门
- php debug_backtrace()
- performSelector: 和dispatch_time及dispatch_once
- libevent
- flume-ng的channe配置type=file例子
- [OpenJudge-NOI]最大子矩阵 贪心
- adb 常用命令
- [转]protobuf数据类型