[DP] [1D1D优化] [树状数组] [最短路] 遭遇战 (clean)
2016-06-05 22:01
429 查看
背景 Background
你知道吗,SQ Class的人都很喜欢打CS。(不知道CS是什么的人不用参加这次比赛)。
题目描述 Description
今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC的人誓死不屈,即将于恐怖分子展开激战,准备让一个人守着A区,这样恐怖分子就不能炸掉服务器了。(一个人就能守住??这人是机械战警还是霹雳游侠?)
但是问题随之出现了,由于DustII中风景秀丽,而且不收门票,所以n名反恐精英们很喜欢在这里散步,喝茶。他们不愿意去单独守在荒无人烟的A区,在指挥官的一再命令下,他们终于妥协了,但是他们每个人都要求能继续旅游,于是给出了自己的空闲时间,而且你强大的情报系统告诉了你恐怖份子计划的进攻时间(从s时刻到e时刻)。
当然,精明的SQC成员不会为你免费服务,他们还要收取一定的佣金(注意,只要你聘用这个队员,不论他的执勤时间多少,都要付所有被要求的佣金)。身为指挥官的你,看看口袋里不多的资金(上头真抠!),需要安排一个计划,雇佣一些队员,让他们在保证在进攻时间里每时每刻都有人员执勤,花费的最少资金。
输入 Input
第一行是三个整数n(1≤n≤10000),s和e(1≤s≤e≤90000)。
接下来n行,描述每个反恐队员的信息:空闲的时间si,ei(1≤si≤ei≤90000)和佣金ci(1≤ci≤300000)。
输出 Output
一个整数,最少需支付的佣金,如果无解,输出“−1”。
样例输入 Sample Input
3 1 5
1 3 3
4 5 2
1 1 1
样例输出 Sample Output
5
提示 Hints
敌人从1时刻到4时刻要来进攻,一共有3名反恐队员。第1名从1时刻到3时刻有空,要3元钱(买糖都不够??)。以此类推。
一共要付5元钱,选用第1名和第2名。
限制 Limits
数据范围见题目
Time Limit : 1s & Memory Limit : 128MB
首先我要吐槽一下题目解释,根本物理没学好好吗?时间是区间而时刻是点好吗?解释一下是打错了还是怎么回事(物理老师闪现)
看题,明显的带权值线段覆盖,DP可以解决权值为1的线段覆盖问题。
思路就是枚举a起点,在a起点的终点之前找到与之覆盖的b起点,b起点覆盖的最小代价已经求出,加上a线段的权值就可以了
那么就有一个严重的问题
求最小值枚举就是个T的,在来个T?T2?可以T了
那么就搞个什么东西维护一下这个DP数组
搞定区间最小值直接上树状数组,O(n+Tlog2T)的时间非常好
上代码
Code
(UPD:这好像是我写的第一个1D1D……)
但是……
还好吧,考场上绝对想不出来
下面就是一个非常优(tou)秀(ji)的方法:转化成图论题
时间区间可以看成从开始到结束的一条边,权值就是边权
为了使图联通,可以反向加边,即i+1时刻到i时刻有一条边权为0的边
上代码
据说正解是堆优化?
下面是标程(pascal党的福音)
DP里优(xia)化(gao)真神奇……
你知道吗,SQ Class的人都很喜欢打CS。(不知道CS是什么的人不用参加这次比赛)。
题目描述 Description
今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC的人誓死不屈,即将于恐怖分子展开激战,准备让一个人守着A区,这样恐怖分子就不能炸掉服务器了。(一个人就能守住??这人是机械战警还是霹雳游侠?)
但是问题随之出现了,由于DustII中风景秀丽,而且不收门票,所以n名反恐精英们很喜欢在这里散步,喝茶。他们不愿意去单独守在荒无人烟的A区,在指挥官的一再命令下,他们终于妥协了,但是他们每个人都要求能继续旅游,于是给出了自己的空闲时间,而且你强大的情报系统告诉了你恐怖份子计划的进攻时间(从s时刻到e时刻)。
当然,精明的SQC成员不会为你免费服务,他们还要收取一定的佣金(注意,只要你聘用这个队员,不论他的执勤时间多少,都要付所有被要求的佣金)。身为指挥官的你,看看口袋里不多的资金(上头真抠!),需要安排一个计划,雇佣一些队员,让他们在保证在进攻时间里每时每刻都有人员执勤,花费的最少资金。
输入 Input
第一行是三个整数n(1≤n≤10000),s和e(1≤s≤e≤90000)。
接下来n行,描述每个反恐队员的信息:空闲的时间si,ei(1≤si≤ei≤90000)和佣金ci(1≤ci≤300000)。
输出 Output
一个整数,最少需支付的佣金,如果无解,输出“−1”。
样例输入 Sample Input
3 1 5
1 3 3
4 5 2
1 1 1
样例输出 Sample Output
5
提示 Hints
敌人从1时刻到4时刻要来进攻,一共有3名反恐队员。第1名从1时刻到3时刻有空,要3元钱(买糖都不够??)。以此类推。
一共要付5元钱,选用第1名和第2名。
限制 Limits
数据范围见题目
Time Limit : 1s & Memory Limit : 128MB
首先我要吐槽一下题目解释,根本物理没学好好吗?时间是区间而时刻是点好吗?解释一下是打错了还是怎么回事(物理老师闪现)
看题,明显的带权值线段覆盖,DP可以解决权值为1的线段覆盖问题。
思路就是枚举a起点,在a起点的终点之前找到与之覆盖的b起点,b起点覆盖的最小代价已经求出,加上a线段的权值就可以了
那么就有一个严重的问题
求最小值枚举就是个T的,在来个T?T2?可以T了
那么就搞个什么东西维护一下这个DP数组
搞定区间最小值直接上树状数组,O(n+Tlog2T)的时间非常好
上代码
Code
(UPD:这好像是我写的第一个1D1D……)
但是……
还好吧,考场上绝对想不出来
下面就是一个非常优(tou)秀(ji)的方法:转化成图论题
时间区间可以看成从开始到结束的一条边,权值就是边权
为了使图联通,可以反向加边,即i+1时刻到i时刻有一条边权为0的边
上代码
#include <queue> #include <cstdio> #include <cstring> #include <climits> #define MAXN 100100 #define MAXT 900100 using namespace std; struct link { int to; int val; int nxt; }; link e[MAXN+MAXT]; int e_num[MAXN],cnt; int n,s,t; int start,finish; int u,v,w; int dis[MAXT],vis[MAXT]; queue <int> q; int mymax(int a,int b) { return a>b?a:b; } int mymin(int a,int b) { return a<b?a:b; } void add(int u,int v,int w) { e[cnt]=(link){v,w,e_num[u]}; e_num[u]=cnt++; } int spfa() { dis[s]=0;vis[s]=true;q.push(s); while (!q.empty()) { int u=q.front();q.pop();vis[u]=false; for (int i=e_num[u];i!=-1;i=e[i].nxt) { if (dis[e[i].to]>dis[u]+e[i].val) { dis[e[i].to]=dis[u]+e[i].val; if (!vis[e[i].to]) { vis[e[i].to]=true; q.push(e[i].to); } } } } if (dis[t]==INT_MAX) return -1; else return dis[t+1]; } int main() { memset(vis,false,sizeof(vis)); memset(e_num,-1,sizeof(e_num)); scanf("%d %d %d",&n,&s,&t); for (int i=1;i<=n;i++) { scanf("%d %d %d",&u,&v,&w); add(mymax(u,s),mymin(v,t)+1,w); } for (int i=s;i<=t+1;i++) { add(i+1,i,0); dis[i]=INT_MAX; } printf("%d",spfa()); return 0; }
据说正解是堆优化?
下面是标程(pascal党的福音)
const maxn=20000; maxt=100000; type re=record data,pos:int64; end; var e,e2,i,n,t,t2,heapsize:longint; a:array [0..maxn,1..3] of int64; f:array [0..maxt] of int64; heap:array [0..maxn] of re; procedure change(var a,b:re); var temp:re; begin temp:=a; a:=b; b:=temp; end; procedure insert(pos,data:int64); var now,next:longint; begin inc(heapsize); heap[heapsize].pos:=pos; heap[heapsize].data:=data; now:=heapsize; while now<>1 do begin next:=now div 2; if heap[now].data>=heap[next].data then exit; change(heap[now],heap[next]); now:=next; end; end; procedure delete; var now,next:longint; begin heap[1]:=heap[heapsize]; heap[heapsize].data:=0; heap[heapsize].pos:=0; dec(heapsize); now:=1; while now*2<=heapsize do begin next:=now*2; if (next<heapsize)and(heap[next+1].data<heap[next].data) then inc(next); if heap[now].data<=heap[next].data then exit; change(heap[now],heap[next]); now:=next; end; end; procedure work; var i:longint; begin heapsize:=1; heap[1].data:=0; heap[1].pos:=0; fillchar(f,sizeof(f),0); for i:=1 to n do begin while (heapsize>0)and(heap[1].pos<a[i,1]-1) do delete; if heapsize=0 then begin writeln(-1); exit; end; if (heap[1].data+a[i,3]<f[a[i,2]])or(f[a[i,2]]=0) then begin f[a[i,2]]:=heap[1].data+a[i,3]; insert(a[i,2],heap[1].data+a[i,3]); end; end; if f[t]=0 then writeln(-1) else writeln(f[t]); end; procedure sor(x,y:longint); var i,k:longint; begin for i:=1 to 3 do begin k:=a[x,i]; a[x,i]:=a[y,i]; a[y,i]:=k; end; end; procedure sort(l,r:longint); var i,j:longint; begin i:=l; j:=r; while i<j do begin while (i<j)and((a[i,1]<a[j,1])or(a[i,1]=a[j,1])and(a[i,2]<=a[j,2])) do j:=j-1; sor(i,j); while (i<j)and((a[i,1]<a[j,1])or(a[i,1]=a[j,1])and(a[i,2]<=a[j,2])) do i:=i+1; sor(i,j); end; if l<i-1 then sort(l,i-1); if j+1<r then sort(j+1,r); end; begin readln(n,e2,t2); e:=e2-1; t:=t2-e; for i:=1 to n do begin readln(a[i,1],a[i,2],a[i,3]); if a[i,1]<e2 then a[i,1]:=e2; if a[i,2]>t2 then a[i,2]:=t2; a[i,1]:=a[i,1]-e; a[i,2]:=a[i,2]-e; end; sort(1,n); work; end.
DP里优(xia)化(gao)真神奇……
相关文章推荐
- java过滤非汉字的utf8的字符
- Mysql逻辑模块组成
- [c语言编程]排序法汇总-入门级别(1)
- TimesTen 数据库复制学习:6. 利用STORE关键字设定复制网络传输的属性
- 1152 - 4 Values whose Sum is 0
- 有一个四位数 a1a2a3a4,每一位数都是0到9之间的一个数字(多种解法)
- Java多线程编程(第三章)
- 6、DownloadManager 下载管理类
- Ubuntu下两个gcc版本切换
- zoj 2476 Total Amount
- c++第七次作业
- 【leetcode】206. Reverse Linked List
- API--Math
- Python Flask Web 第十课 —— flask-wtf
- 第二阶段冲刺(第十天)
- PHPExcel 导出表格 不知道好不好用
- springmvc参数绑定
- JS放大镜特效(兼容版)
- Adaboost原理、算法以及应用
- Web之浅谈前端开发-基于最基础的前端技术