Intervals
设s[k]表示0~k之间最少选出的个整数。由题意可得:s[bi]-s[ai-1]>=ci;
这很明显是一个差分约束系统的模型。
但是题目中仍有一些隐含条件:
1.s[k]-s[k-1]>=0,很明显。
2.s[k]-s[k-1]<=1.每个数只能选一次,可变形为s[k-1]-s[k]>=-1;
但是只这样做的话,因为a最小为0,所以我们会得到-1这个点,这样不方便,所以可以把0~k都加上一个1.
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
#include<algorithm>
#include<stack>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
using namespace std;
const int maxn=50100;
int read()
{
int res=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
res=res*10+ch-'0';
ch=getchar();
}
return res*f;
}
int n;
int head[maxn],next1[3*maxn],to[3*maxn],dis[maxn],w[3*maxn],cnt;
int vis[maxn],mn;
inline void add(int u,int v,int weight)
{
cnt++;
next1[cnt]=head[u];
head[u]=cnt;
to[cnt]=v;
w[cnt]=weight;
}
inline void spfa()
{
memset(dis,0xc0,sizeof(dis));dis[0]=0;
queue<int>q;q.push(0);vis[0]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=next1[i])
{
int v=to[i];
int ww=w[i];
if(dis[v]<dis[u]+ww)
{
dis[v]=dis[u]+ww;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
int main()
{
n=read();
rep(i,1,n)
{
int u,v,weight;
u=read();v=read();weight=read();
add(u,v+1,weight);
mn=max(mn,v+1);
}
rep(i,1,mn)
{
add(i-1,i,0);
add(i,i-1,-1);
}
spfa();
printf("%d\n",dis[mn]);
return 0;
}