NKOI 1385 笨笨种西瓜

                                                           笨笨种西瓜

Time Limit:10000MS  Memory Limit:165536K
Total Submit:163 Accepted:82
Case Time Limit:1000MS

Description

笨笨种了一块西瓜地,但这块西瓜地的种植范围是一条直线的……
笨笨在一番研究过后,得出了m个结论,这m个结论可以使他收获的西瓜最多。
笨笨的结论是这样的:
从西瓜地B处到E处至少要种植T个西瓜,这个范围的收获就可以最大化。
笨笨不想那么辛苦,每个位置最多种一个西瓜,所以他想种植的西瓜尽量少,而又满足每一个所得的结论。

Input

第一行两个数n,m(0<n<=5000,0<=m<=3000),表示笨笨的西瓜地长n,笨笨得出m个结论。
接下来m行表示笨笨的m个结论,每行三个数b,e,t(1<=b<=e<=n,0<=t<=e-b+1)。

Output

输出笨笨最少需种植多少西瓜。

Sample Input

9 4
1 4 2
4 6 2
8 9 2
3 5 2

Sample Output

5

Hint

基本上来说,笨笨的西瓜地就是一条壮观的线……

这道题除了题目中给出的约束条件外其实还有两个题目中暗示的约束条件

那么所有的约束条件如下:

1:题目要求两个点(b和e)之间至少需要t个,就相当于Se-S(b-1)>=t
2:一个点至少要种0个,就是Si-S(i-1)>=0
3:一个点最多种1个(暂且这样认为),就是Si-S(i-1)<=1,移项得到S(i-1)-Si>=-1
然后再增加一个虚拟节点,到所有点的权值为0,再求最长路就行了

#include<cstdio>
#include<iostream>
#include<queue>
#define inf 2e9
using namespace std;
int n,m,cnt;
void _read(int &d){
	d=0;
	char t=getchar();
	for(d=0;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)+t-'0';
}
int next[300005],end[300005],last[300005],len[300005];
int dis[300005];
bool f[300005];
queue<int>q;
void fst(int a,int b,int l){
	end[++cnt]=b;
	len[cnt]=l;
	next[cnt]=last[a];
	last[a]=cnt;
}
void spfa(){
	int i,y,t,x;
    for(i=n;i>=1;i--)dis[i]=-inf;
    q.push(0);
	f[0]=true;
	dis[0]=0;
    while(!q.empty()){
        x=q.front();
		q.pop();
		f[x]=false;
        t=last[x];
        while(t!=0){
           y=end[t];
           if(dis[x]+len[t]>dis[y]){
                  dis[y]=dis[x]+len[t];
                  if(!f[y]){
                      f[y]=true; 
                      q.push(y);
                  }
           } 
           t=next[t];
		}
    }
}
int main(){
	int i,e,b,c;
	_read(n);_read(m);
	for(i=n;i>=1;i--){
		fst(0,i,0);
		fst(i,i-1,-1);
		fst(i-1,i,0);
	}
	for(i=1;i<=m;i++){
		_read(b);
		_read(e);
		_read(c);
		fst(b-1,e,c);
	}
	spfa();
	cout<<dis[n];
}
一直wrong answer的话可以试一试这组数据

6 3
1 3 2
2 6 3
4 6 1

3


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值