【codevs】线段覆盖系列 贪心&&动规
来源:互联网 发布:和男友过夜 知乎 编辑:程序博客网 时间:2024/05/17 03:25
线段覆盖
贪心,不说了。
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int size=1000010;struct edge{ int l,r;}l[size];bool cmp(const edge &a,const edge &b){ return a.r<b.r;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&l[i].l,&l[i].r); if(l[i].l>l[i].r) swap(l[i].l,l[i].r); } sort(l+1,l+1+n,cmp); int ans=0; for(int i=1,last=-2333;i<=n;i++) { if(last<=l[i].l) { last=l[i].r; ans++; } } printf("%d",ans); return 0;}
线段覆盖2
这个是dp。
按右端点排序。
dp[i]代表当第i个线段是被选择的最后一个线段后,所达到的最大价值。
所以状态转移方程:
dp[i]=max{dp[i],dp[j]+l[i].d} (j<i && l[i].l>=l[j].r)
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int size=23333;int dp[size];struct edge{ int l,r,d;}l[size];bool cmp(const edge &a,const edge &b){ return a.r<b.r;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&l[i].l,&l[i].r,&l[i].d); sort(l+1,l+1+n,cmp); int ans=0; for(int i=1;i<=n;i++) { dp[i]=l[i].d; for(int j=1;j<i;j++) { if(l[j].r<=l[i].l) { dp[i]=max(dp[i],dp[j]+l[i].d); } } ans=max(dp[i],ans); } printf("%d",ans); return 0;}/*107 8 11 7 20 3 34 9 40 6 55 7 60 3 77 8 87 10 94 7 10*/
线段覆盖3
贪心,和第一个一样。
线段覆盖4
这个也是dp,不过n太大,不能n^2。
可以改变状态的表示。
dp[i]代表选到坐标i的时候所拿到的最大价值。
状态转移方程:
dp[i]=max{ dp[i],max{ dp[1],dp[2],...,dp[i-1] }+l[i].d }
但因为是线段,所以可以这样:
dp[l[i].r]=max{ dp[i],max{dp[1],dp[2]...,dp[l[i].l]}+l[i].d }
因为要先确定dp[l[i].l]
,所以应该把坐标按左端点排序。
如何选取1~l[i].l
的最大值?
树状数组!
这样就优化到O(nlogn)
代码:
#include<cstring>#include<iostream>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const LL size=1000010;const LL INF=(LL)1e15;struct edge{ LL l,r; LL d;}l[size];LL dp[size];bool cmp(const edge &a,const edge &b){ return a.l<b.l;}LL bits[size];void add(LL x,LL d){ for(LL i=x;i<=size-10;i+=i&(-i)) { bits[i]=max(bits[i],d); }}LL ask(LL x){ LL ans=0; for(LL i=x;i>0;i-=i&(-i)) { ans=max(ans,bits[i]); } return ans;}int main(){ LL n; scanf("%lld",&n); for(LL i=1;i<=n;i++) scanf("%lld%lld%lld",&l[i].l,&l[i].r,&l[i].d); sort(l+1,l+1+n,cmp); LL ans=0; for(LL i=1;i<=n;i++) { dp[l[i].r]=max(dp[l[i].r],ask(l[i].l)+l[i].d); ans=max(ans,dp[l[i].r]); add(l[i].r,dp[l[i].r]); } printf("%lld",ans); return 0;}
线段覆盖5
坐标离散化,就和4一样了。
听说卡P党?
代码:
#include<cstring>#include<iostream>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const LL size=2000010;const LL INF=(LL)1e15;struct edge{ LL l,r; LL d;}l[size];bool cmp(const edge &a,const edge &b){ return a.l<b.l;}LL lsh[size];LL dp[size],bits[size];void add(LL x,LL d){ for(LL i=x;i<=size-10;i+=i&-i) { bits[i]=max(bits[i],d); }}LL ask(LL x){ LL ans=0; for(LL i=x;i>0;i-=i&-i) { ans=max(bits[i],ans); } return ans;}int main(){ LL n; scanf("%lld",&n); for(LL i=1;i<=n;i++) { scanf("%lld%lld%lld",&l[i].l,&l[i].r,&l[i].d); lsh[++lsh[0]]=l[i].l; lsh[++lsh[0]]=l[i].r; } sort(lsh+1,lsh+1+lsh[0]); LL len=unique(lsh+1,lsh+1+lsh[0])-lsh-1; for(LL i=1;i<=n;i++) { l[i].l=lower_bound(lsh+1,lsh+1+len,l[i].l)-lsh; l[i].r=lower_bound(lsh+1,lsh+1+len,l[i].r)-lsh; } //for(LL i=1;i<=n;i++) printf("%d %d %d\n",l[i].l,l[i].r,l[i].d); sort(l+1,l+1+n,cmp); LL ans=0; for(LL i=1;i<=n;i++) { dp[l[i].r]=max(dp[l[i].r],l[i].d+ask(l[i].l)); ans=max(ans,dp[l[i].r]); add(l[i].r,dp[l[i].r]); } printf("%lld",ans); return 0;}/*5233 2333 1100 1000 2123 321 3444 555 412 450 5*/
总结:序列型动规应该是比较简单的,但刷多了还是恶心…
1 0
- 【codevs】线段覆盖系列 贪心&&动规
- codevs 线段覆盖系列
- codevs 1124线段覆盖(贪心)
- 动规:线段覆盖
- 【贪心】【排序】【codevs 1214】线段覆盖
- codevs 1214 线段覆盖 贪心 解题报告
- codevs 1214 线段覆盖(贪心)
- 【专题·线段覆盖系列】Codevs线段覆盖12345
- codevs 1214 线段覆盖(贪心 or dp)
- codevs 1643 线段覆盖 3(贪心+快排)
- 线段覆盖系列(dp+贪心)
- codevs 1214 线段覆盖
- 【codevs 1214】线段覆盖
- Codevs 1214 线段覆盖
- CODEVS 1214线段覆盖
- codeVS 1214 线段覆盖
- codevs 1214 线段覆盖
- 线段覆盖 CODEVS
- 14年到15年失败堕落的一年
- iOS地图系统导航
- Dijkstra||Prim-POJ-1797-Heavy Transportation
- Largest Rectangle in Histogram
- 【.Net码农】App.Config详解及读写操作
- 【codevs】线段覆盖系列 贪心&&动规
- 测试数据库数据所在硬件写性能的脚本
- Ubuntu中root用户和user用户的相互切换(转)
- ERROR:process fail witherrorcode -61101
- UITableView相关问题
- Naive Bayes笔记
- 回家
- 多态
- ubuntu 下权限学习