POJ 2373 Dividing the Path(队列dp)
2016-09-07 19:34
309 查看
这题的模型是给予2A~2B间隔为2的板子,用最少的板子覆盖线段L。
那么设f(x)代表覆盖线段x最少用的板子,那么结果就是f(L)了。
当x为奇数时,f[x]=inf;
当x有奶牛时,发[x]=inf;
当x<2A时,f[x]为inf。
那么当x大于等于2A小于等于2B,f为1。
从i=2B+2开始,就要开始dp了。从i-2B到i-2A从选一个最小的加一,知道i为L。
如果选择遍历,那肯定会超时,所以用优先队列,取队头,合适就咬,不合适就继续取,当时不能把大于i-2A的放入,因为之后还要用,所以不能丢,但不丢又不能取下一个,所以会导致dp无法进行。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/9/7.
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct Fx{
int f,p;
Fx(int f=0,int p=0): f(f),p(p) {}
bool operator < (const Fx &e) const {
return f>e.f;
}
};
const int inf=99999999;
const int maxn=1000000+100;
int Cowthere[maxn],f[maxn];
int main()
{
memset(f,0,sizeof(f));
memset(Cowthere,0,sizeof(Cowthere));
int n,l;
int a,b;
int s,e;
cin>>n>>l;
cin>>a>>b;
a<<=1;b<<=1;
for(int i=0;i<n;i++)
{
cin>>s>>e;
Cowthere[s+1]++;
Cowthere[e]--;
}
int nowCow=0;
for(int i=0;i<=l;i++)
{
f[i]=inf;
nowCow+=Cowthere[i];
Cowthere[i]=nowCow>0;
}
priority_queue<Fx> pq;
for(int i=a;i<=b;i+=2)
{
if(!Cowthere[i]){
f[i]=1;
if(i<=b+2-a) pq.push(Fx(1,i));
}
}
for(int i=b+2;i<=l;i+=2)
{
if(!Cowthere[i])
{
Fx ff;
while(!pq.empty())
{
ff=pq.top();
if(ff.p<i-b) pq.pop();
else break;
}
if(!pq.empty())
f[i]=ff.f+1;
}
if(f[i-a+2]!=inf)
pq.push(Fx(f[i-a+2],i-a+2));
}
if(f[l]==inf)
cout<<-1<<endl;
else
cout<<f[l]<<endl;
return 0;
}
那么设f(x)代表覆盖线段x最少用的板子,那么结果就是f(L)了。
当x为奇数时,f[x]=inf;
当x有奶牛时,发[x]=inf;
当x<2A时,f[x]为inf。
那么当x大于等于2A小于等于2B,f为1。
从i=2B+2开始,就要开始dp了。从i-2B到i-2A从选一个最小的加一,知道i为L。
如果选择遍历,那肯定会超时,所以用优先队列,取队头,合适就咬,不合适就继续取,当时不能把大于i-2A的放入,因为之后还要用,所以不能丢,但不丢又不能取下一个,所以会导致dp无法进行。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/9/7.
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct Fx{
int f,p;
Fx(int f=0,int p=0): f(f),p(p) {}
bool operator < (const Fx &e) const {
return f>e.f;
}
};
const int inf=99999999;
const int maxn=1000000+100;
int Cowthere[maxn],f[maxn];
int main()
{
memset(f,0,sizeof(f));
memset(Cowthere,0,sizeof(Cowthere));
int n,l;
int a,b;
int s,e;
cin>>n>>l;
cin>>a>>b;
a<<=1;b<<=1;
for(int i=0;i<n;i++)
{
cin>>s>>e;
Cowthere[s+1]++;
Cowthere[e]--;
}
int nowCow=0;
for(int i=0;i<=l;i++)
{
f[i]=inf;
nowCow+=Cowthere[i];
Cowthere[i]=nowCow>0;
}
priority_queue<Fx> pq;
for(int i=a;i<=b;i+=2)
{
if(!Cowthere[i]){
f[i]=1;
if(i<=b+2-a) pq.push(Fx(1,i));
}
}
for(int i=b+2;i<=l;i+=2)
{
if(!Cowthere[i])
{
Fx ff;
while(!pq.empty())
{
ff=pq.top();
if(ff.p<i-b) pq.pop();
else break;
}
if(!pq.empty())
f[i]=ff.f+1;
}
if(f[i-a+2]!=inf)
pq.push(Fx(f[i-a+2],i-a+2));
}
if(f[l]==inf)
cout<<-1<<endl;
else
cout<<f[l]<<endl;
return 0;
}
相关文章推荐
- poj 2373 Dividing the Path(dp+单调队列优化)
- POJ 2373 (Dividing the Path)单调队列优化DP
- POJ 2373 Dividing the Path DP -
- poj - 2373 Dividing the Path
- [USACO2004][poj2373]Dividing the Path(DP+单调队列)
- POJ2373:Dividing the Path
- POJ 2373 Dividing the Path
- POJ 2373 Dividing the Path(灌溉草场)
- POJ-2373-Dividing the Path
- POJ 2373-Dividing the Path解题报告
- 【poj2373】Dividing the Path【单调队列优化dp】
- POJ 2373 Dividing the Path(线段树+dp)
- poj2373 Dividing the Path 单调队列dp
- poj 2373 Dividing the Path
- poj 2373 Dividing the Path
- POJ 2373 Dividing the Path
- POJ_3017 Cut the Sequence 单调队列+dp+BST
- poj 2373(单调队列优化dp)
- POJ2373 Dividing the Path——动态规划+单调队列优化
- poj 3017 Cut the Sequence(dp单调队列优化)