URAL 1303
题目大意:给出N个区间[Li,Ri](1<=i<=N),一个正整数M,求N个区间里,并区间包含[0,M]的区间的最小个数(无解时输出:No solution)。
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
数据规模:1<=M<=5000,-50000<=Li<Ri<=50000,1<=N<=99999。
理论基础:无。
题目分析:用贪心法。
首先,预处理,除去所有可以被别的区间包含的区间,可以证明,这样以后,得出的最优解不会劣于未处理前。
证明:假设原解用到区间[a,b]包含于[m,n]那么将原解中的区间替换为[m,n]答案不会变劣,证毕。
还可以证明,在所有能够覆盖左端点的区间中选择最靠近左端点的区间得到的解不会劣于原解。
证明:假设原解中有区间[a,b],现有区间[m,n],a<m由预处理知,各区间互不包含所以b<n,那么[a,b]覆盖的区域,[m,n]也可以将其覆盖,因为[m,n]也可以覆盖左端点,而n>b,所以必然也可以覆盖右端点,这样结果不劣于原解。所以命题得证。
贪心策略:每次找到一个区间后,将左端点更新为此区间的右端点,再进行寻找。直到找到的区间的右端点覆盖了M为止。
最后,我们来证明这样贪心得出的解必为最优解,假设不是最优解,那么必然有一个区间可以去除。
1.假设此区间为第一个区间,则根据贪心策略,有第二个区间不覆盖左端点(如果覆盖的话,选择的第一个区间即为此区间),去掉第一个区间后,则左端点没有被覆盖,所以此区间不可去除。
2.假设此区间为最后一个区间,同1,如果去除此区间后,则右端点未被覆盖,所以不可去除。
3.假设此区间为相邻的三个区间[a,b],[x,y],[m,n]中的[x,y]。则根据贪心策略存在d属于区间[x,y]有:a<x<b<m<y<n,如果去掉[x,y],则区间[b,m]未被覆盖,所以不可去除。
综上所述,贪心策略所得解中所有区间都不可去除,所以必为最优解。得证。
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<ctime>
#include<vector>
using namespace std;
typedef double db;
#define DBG 0
#define maa (1<<31)
#define mii ((1<<31)-1)
#define ast(b) if(DBG && !(b)) { printf("%d!!|\n", __LINE__); while(1) getchar(); } //调试
#define dout DBG && cout << __LINE__ << ">>| "
#define pr(x) #x"=" << (x) << " | "
#define mk(x) DBG && cout << __LINE__ << "**| "#x << endl
#define pra(arr, a, b) if(DBG) {\
dout<<#arr"[] |" <<endl; \
for(int i=a,i_b=b;i<=i_b;i++) cout<<"["<<i<<"]="<<arr[i]<<" |"<<((i-(a)+1)%8?" ":"\n"); \
if((b-a+1)%8) puts("");\
}
template<class T> inline bool updateMin(T& a, T b) { return a>b? a=b, true: false; }
template<class T> inline bool updateMax(T& a, T b) { return a<b? a=b, true: false; }
typedef long long LL;
typedef long unsigned int LU;
typedef long long unsigned int LLU;
#define N 100000
pair <int,int> s[N+5],pre[N+5],ans[N+5];
int m,cnt,np,na;
ostream& operator << (ostream& out,pair <int,int> a)
{
printf("%d %d\n",a.first,a.second);
return out;
}
bool fun(pair <int,int> a,pair <int,int> b)
{
if(a.first!=b.first)return a.first<b.first;
else return a.second<b.second;
}
void solve()
{
int left=0,right=m,now=0;
while(now<=np&&left<right)
{
while(now<=np&&pre[now].first<=left)now++;
if(now==0)break;
if(pre[now-1].first<=left)
{
ans[na++]=pre[now-1];
left=pre[now-1].second;
}
}
if(left>=right)
{
printf("%d\n",na);
for(int i=0;i<na;i++)cout<<ans[i];
}
else printf("No solution\n");
}
int main()
{
scanf("%d",&m);
while(1)
{
int a,b;
scanf("%d%d",&a,&b);
if(a!=0||b!=0)
{
s[cnt].first=a;
s[cnt++].second=b;
}
else break;
}
sort(s,s+cnt,fun);
pra(s,0,cnt-1)
pre[0]=s[0];
for(int i=1;i<cnt;i++)
{
if(s[i].first==pre[np].first)pre[np]=s[i];
else if(s[i].second<=pre[np].second);
else pre[++np]=s[i];
}
pra(pre,0,np)
solve();
return 0;
}
其中,ans[i]即为用来存储所选区间的数组。
by:Jsun_moon http://blog.csdn.net/Jsun_moon
URAL 1303的更多相关文章
- 贪心 URAL 1303 Minimal Coverage
题目传送门 /* 题意:最少需要多少条线段能覆盖[0, m]的长度 贪心:首先忽略被其他线段完全覆盖的线段,因为选取更长的更优 接着就是从p=0开始,以p点为标志,选取 (node[i].l < ...
- URAL 1303 Minimal Coverage
URAL 1303 思路: dp+贪心,然后记录路径 mx[i]表示从i开始最大可以到的位置 sufmx[i]表从1-i的某个位置开始最大可以到达的位置 比普通的贪心效率要高很多 代码: #inclu ...
- ural 1303 Minimal Coverage【贪心】
链接: http://acm.timus.ru/problem.aspx?space=1&num=1303 http://acm.hust.edu.cn/vjudge/contest/view ...
- Ural 1303 Minimal Coverage(贪心)
题目地址:Ural 1303 先按每一个线段的左端点排序,然后设置一个起点s.每次都从起点小于等于s的线段中找到一个右端点最大的. 并将该右端点作为新的起点s,然后继续找. 从左到右扫描一遍就可以. ...
- ural 1303 Minimal Coverage(贪心)
链接: http://acm.timus.ru/problem.aspx?space=1&num=1303 按照贪心的思想,每次找到覆盖要求区间左端点时,右端点最大的线段,然后把要求覆盖的区间 ...
- URAL 1303. Minimal Coverage(DP)
题目链接 又是输出路径...这题完全受上题影响,感觉两个题差不多..用了基本上一样的算法写了,这题比较纠结,就是卡内存啊...5000*5000的数组开不了..然后没办法,水了好几次MLE,看了一下虎 ...
- URAL DP第一发
列表: URAL 1225 Flags URAL 1009 K-based Numbers URAL 1119 Metro URAL 1146 Maximum Sum URAL 1203 Scient ...
- Contest 7.21(贪心专练)
这一次都主要是贪心练习 练习地址http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26733#overview Problem APOJ 13 ...
- [置顶] 2013_CSUST暑假训练总结
2013-7-19 shu 新生训练赛:母函数[转换成了背包做的] shuacm 题目:http://acm.hdu.edu.cn/diy/contest_show.php?cid=20083总结:h ...
随机推荐
- D - Common Subsequence
D - Common Subsequence Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I ...
- 在ProgressBar上加文字----显示百分比的进度条
http://www.cnblogs.com/3dant/archive/2011/04/25/2026776.html
- halcon与C#混合编程
halcon源程序: dev_open_window(0, 0, 512, 512, 'black', WindowHandle)read_image (Image, 'C:/Users/BadGuy ...
- web编程速度大比拼(nodejs go python)(非专业对比)
C10K问题的解决,涌现出一大批新框架,或者新语言,那么问题来了:到底谁最快呢?非专业程序猿来个非专业对比. 比较程序:输出Hello World! 测试程序:siege –c 100 –r 100 ...
- 5_Navigation Bar
5 // // ViewController.swift // Navigation Bar // // Created by ZC on 16/1/9. // Copyright © 2016年 Z ...
- 阿里云ECS每天一件事D6:安装nginx-1.6.2
自从接触nginx就开始喜欢上这个小东西了,似乎没什么特别的原因,就是喜欢而已. 1.安装环境的准备 yum install pcre pcre-devel openssl openssl-devel ...
- 转: angular编码风格指南
After reading Google's AngularJS guidelines, I felt they were a little too incomplete and also guide ...
- SSD常见问题的技术分析
AHCI对性能的影响 AHCI,全称Advanced Host Controller Interface,即高级主机控制器接口,是一种相比老旧的“IDE虚拟模式”更适合新一代SATA存储设备通信的协议 ...
- iOS中菊花。。。
其实系统的菊花除了功能有点单一,不具有刷新页面的功能以外,其他都还好吧,满足你一些正常的提示功能还是绰绰有余的:直接把项目里面的代码粘出来吧,其实也没有什么特别要注意的地方,一些设置属性也算留个备份 ...
- android程序启动画面之Splash总结[转]
方法一: 很多应用都会有一个启动界面.欢迎画面慢慢隐现,然后慢慢消隐.实现这种效果的方法有两种(暂时只发现两种)1.使用两个Activity,程序启动时候load第一张Activity,然后由tick ...