[贪心][Usaco2010 Mar]balloc 农场分配
2013-10-15 21:49
447 查看
solution:
我们将所有区间按照左端点排序后,从右往左,能添加则添加不能就不添加,这样贪心是正确的。因为我们可以维护两个性质:
1.最大性
2.方案对后面的区间一定是最优的。证明略。
能这么做的原因是因为这道题是无权的。
假如区间有权的话,那么等价于选出K条路径,路径上每个区间不相交且权值最大,可以用费用流做。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int M=100010; int n,m,res,x,y; int t[M<<2],s[M<<2]; struct Node { int u,v; friend bool operator < (const Node a,const Node b) { if(a.u==b.u)return a.v<b.v; else return a.u<b.u; } }a[M]; void build(int o,int l,int r) { if(l==r) { scanf("%d",&t[o]); return; } int M=l+r>>1; build(o<<1,l,M); build(o<<1|1,M+1,r); t[o]=min(t[o<<1],t[o<<1|1]); } inline void pushdown(int o) { if(s[o]) { int l=o<<1; int r=l+1; s[l]+=s[o]; s[r]+=s[o]; t[l]-=s[o]; t[r]-=s[o]; s[o]=0; } } int ask(int o,int l,int r) { if(x<=l && y>=r)return t[o]; pushdown(o); int M=l+r>>1,ans=M; if(x<=M)ans=min(ans,ask(o<<1,l,M)); if(y>M)ans=min(ans,ask(o<<1|1,M+1,r)); return ans; } void update(int o,int l,int r) { if(x<=l && y>=r) { t[o]--; s[o]++; return; } pushdown(o); int M=l+r>>1; if(x<=M)update(o<<1,l,M); if(y>M)update(o<<1|1,M+1,r); t[o]=min(t[o<<1],t[o<<1|1]); } int main() { scanf("%d %d",&n,&m); build(1,1,n); for(int i=1;i<=m;++i) scanf("%d %d",&a[i].u,&a[i].v); sort(a+1,a+1+m); for(int i=m;i>=1;--i) { x=a[i].u; y=a[i].v; if(ask(1,1,n)<1)continue; res++; update(1,1,n); } printf("%d\n",res); return 0; }
相关文章推荐
- linux环境jdk安装及配置
- 一致性哈希算法 - Consistent Hashing
- TNS连接和服务名杂记
- 远程桌面
- Delphi XE5 for Android (九)
- 幂集的递归回溯求解
- 移植1- 裸写BL1,启动uboot
- 1043. Is It a Binary Search Tree (25)
- Jungle Roads
- windows server 2008 r2的FTP配置和访问
- C语言中头文件是如何包含的?也说重定义
- 敏捷软件之弊
- 截断上传原理(转载加自己实验)
- python,xml,dom,tree,parser,soup,beautiful soup
- 撰写商业计划书
- So cute are you Python 8
- Spring.Net 技术简介 IOC and DI
- Extjs 继承Ext.Component自定义组件
- UVALive 4670 Dominating Patterns(AC自动机模板题)
- 安卓应用退出的实现 推荐