题意: 给出X轴上N个点的坐标 X轴上的点按大小两两互相连通 现在要必须干掉K条路 求最小花费
分析: dp+线段树优化 我表示不会 copy一遍题解
首先题目给出的城市坐标不是按X轴升序的, 那么我们就将每个城市根据坐标从左到右映射到X轴上的1~n
设dp[i]:= 到第 i 个点(包括第i个点)时, 处理掉前面所有必须不连通的道路的最小花费。
由于道路可能存在包含关系, 此时必定是选取最右边的左端点L作为区间左端点(假设每条道路从左端点开始, 右端点结束)
否则选取其他的点只会徒增花费
那么 dp[i] = min{dp[j] + len( j , j+1) }, L <= j < i, 其中len(j , j+1) 表示映射到坐标轴上的城市的距离
我们用线段树来维护dp[j] + len( j , j+1) 的最小值 每次处理完后将dp[i] + len (i, i+1) 插入到i
然后就可以ac了
代码:
//
// Created by TaoSama on 2015-09-21
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
题意: 每个ACMer有能力, 价格, 每个题目有难度 现在小Z有L钱 问怎么请ACMer才能最少的天数完成
分析: 贪心啦 红果果的set贪心 将ACMer和题目按照 能力、难度大到小排序 先搞大的 大的都不能搞还搞毛
把可以解决当前题目的ACMer都丢进set里 然后找一个最便宜的 如此贪心
天数二分就可以了 能干掉这个题 继续干掉比它小的天数-1个题
代码: 据说PQ会快点 set习惯了
//
// Created by TaoSama on 2015-09-21
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
s;
int cost = 0;
for(int i = 1, j = 1; i <= m;) {
while(j <= n && A[j].a >= B[i].a) s.insert(P(A[j].c, A[j].id)), j++;
if(!s.size()) return false;
cost += s.begin()->first;
if(cost > l) return false;
int t = x, id = s.begin()->second;
s.erase(s.begin());
while(t-- && i <= m) ans[B[i++].id] = id;
}
return true;
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(scanf("%d%d%d", &n, &m, &l) == 3) {
for(int i = 1; i <= n; ++i) scanf("%d", &A[i].a);
for(int i = 1; i <= n; ++i) scanf("%d", &A[i].c), A[i].id = i;
for(int i = 1; i <= m; ++i) scanf("%d", &B[i].a), B[i].id = i;
sort(A + 1, A + 1 + n);
sort(B + 1, B + 1 + m);
int l = 0, r = 1e5;
while(l <= r) {
int m = l + r >> 1;
if(check(m)) r = m - 1;
else l = m + 1;
}
if(check(l)) {
puts("Good Luck");
for(int i = 1; i <= m; ++i) printf("%d%c", ans[i], " \n"[i == m]);
} else puts("Do it yourself");
}
return 0;
}
题意: 求连续的最大矩形
分析: 单调栈或者dp维护从i这个位置能向左右延伸的最大值 不同的是单调栈是() dp是[]
代码:
//
// Created by TaoSama on 2015-09-21
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
题意: 长度为N的环 求长度不超过M的最大连续和以及位置 多解输出最短的优先 然后字典序小的优先
分析: 线段树区间合并 直接维护答案直接搞 倍增一下查询N次M大小的区间 更新答案就好
代码:
//
// Created by TaoSama on 2015-09-21
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
分析: 考虑最大连续和=整个序列的前缀和-当前M大小区间的最小前缀和
我们维护一个M+1大小的单调队列 - - 多一个好写代码 减的时候把这个多的减掉就好了
注意特判全为负数的情况 样例很强就不多说了
代码:
//
// Created by TaoSama on 2015-09-22
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
题意: 单点更新 环上区间RMQ
分析: 线段树模版题 - - 题目没说人走的方向啊 所以l>r是可以的
代码:
//
// Created by TaoSama on 2015-09-21
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include