POJ1201 Intervals & TYVJ 1415 西瓜种植 差分约束

$ \rightarrow $ 戳我进TYVJ原题

西瓜种植

题目限制

时间限制内存限制评测方式题目来源
1000ms131072KiB标准比较器Local

 

题目背景

笨笨:小西瓜,小西瓜~
路人甲:不会呀,这西瓜明明就大着啊……
笨笨:那……大西瓜,大西瓜~
路人甲:这么快就改口了……
笨笨:西瓜西瓜~可爱的西瓜~
 

题目描述

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

输入格式

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

输出格式

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

提示

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

样例数据

输入样例 #1
 9 4
 1 4 2
 4 6 2
 8 9 2
 3 5 2
输出样例 #1
 5

$ \rightarrow $ 戳我进POJ原题

Intervals

Time Limit: 2000MS Memory Limit: 65536K

 

Description

You are given $ n $ closed, integer intervals $ [a_i,b_i] $ and n integers $c_1, \dots ,c_n $ .
Write a program that:
reads the number of intervals, their end points and integers $c_1, \dots ,c_n $ from the standard input,
computes the minimal size of a set $ Z $ of integers
which has at least ci common elements with interval $ [a_i,b_i] $ , for each $ i=1,2,\dots,n $,
writes the answer to the standard output.
 

Input

The first line of the input contains an integer $ n (1 \le n \le 50000) $-- the number of intervals.
The following $ n $ lines describe the intervals.
The $ (i+1)-th $ line of the input contains three integers $ a_i, b_i $ and $ c_i $ separated by single spaces
and such that $ 0 \le a_i \le b_i \le 50000 $ and $ 1 \le c_i \le b_i - a_i+1 $ .
 

Output

The output contains exactly one integer equal to the minimal size of set $ Z $
sharing at least ci elements with interval $ [a_i, b_i] $ , for each $ i=1,2,\dots,n $.
 

Sample Input

 5
 3 7 3
 8 10 3
 6 8 1
 1 3 1
 10 11 1

Sample Output

 6

 

Source

Southwestern Europe 2002


题目大意及题解代码

  • 给定 $ n $ 个闭区间 $ [a_i,b_i] (1 \le n, 0 \le a_i,b_i \le 50000) $ 和 $ n $ 个整数 $ c_i (1 \le i \le n ) $ .

  • 你需要构造一个整数集合 $ Z $ ,使得 $ \forall i \in [1,n], Z $ 中满足 $ a_i \le x \le b_i $ 的整数 $ x $ 不少于 $ c_i $ 个。

  • 求这样的整数集合 $ Z $ 最少包含多少个数。


  • 设 $ s[k] $ 表示 $ 0 $ 到 $ k $ 之间最少选出多少个整数。根据题意,有 $ s[b_i]-s[a_i-1] \ge c_i $ 。这很明显是一个差分约束系统的模型。

  • 不过,我们还要增加一些隐含的条件,才能保证求出的解是有意义的:

  • $ 1) s[k]-s[k-1] \ge 0 . 0 $ 到 $ k $ 之间选出的书肯定在 $ 0 $ 到 $ k-1 $ 内。

  • $ 2) s[k]-s[k-1] \le 1 . $ 每个数只能被选一次。可变形为 $ s[k-1]-s[k] \ge -1 . $

//POJ 1201
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring> 
#include<vector>
#include<queue> 
using namespace std;
#define maxn 50005
struct edge{ int v,w; };
vector<edge>E[maxn];
int n,minv,maxv,dis[maxn];
bool vis[maxn];
inline void spfa(){
    memset(dis,-0x3f,sizeof(int)*(maxv+1)); queue<int>q;
    q.push(minv-1); dis[minv-1]=0; vis[minv-1]=1;
    while(!q.empty()){
        int u=q.front(); q.pop(); vis[u]=0;
        for(int i=0;i<E[u].size();++i){
            int v=E[u][i].v,w=E[u][i].w;
            if(dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                if(!vis[v]){ vis[v]=1; q.push(v); }
            }
        }
    }
}
int main(){
    while(scanf("%d",&n)!=EOF){
        minv=maxn; maxv=0;
        for(int i=0;i<maxn;++i) E[i].clear();
        for(int u,v,w,i=1;i<=n;++i){
            scanf("%d %d %d",&u,&v,&w);
            E[u-1].push_back(edge{v,w});
            if(u<minv) minv=u; 
            if(v>maxv) maxv=v;
        }
        for(int i=minv;i<=maxv;++i){
            E[i-1].push_back(edge{i,0});
            E[i].push_back(edge{i-1,-1});
        }
        spfa();
        printf("%d",dis[maxv]);
    }
    return 0;
}

//TYVJ 1415
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring> 
#include<vector>
#include<queue> 
using namespace std;
#define maxn 5005
vector<int>E[maxn],W[maxn];
int n,m,dis[maxn];
bool vis[maxn];
inline void spfa(){
    memset(dis,0x7f,sizeof(int)*(n+1)); queue<int>q;
    q.push(0); dis[0]=0; vis[0]=1;
    while(!q.empty()){
        int u=q.front(); q.pop(); vis[u]=0;
        for(int i=0;i<E[u].size();++i){
            int v=E[u][i],w=W[u][i];
            if(dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                if(!vis[v]){ vis[v]=1; q.push(v); }
            }
        }
    }
}
int main(){
    scanf("%d %d",&n,&m);
    for(int u,v,w,i=1;i<=m;++i){
        scanf("%d %d %d",&u,&v,&w);
        E[u-1].push_back(v);
        W[u-1].push_back(w);
    }
    for(int i=1;i<=n;++i){
        E[i-1].push_back(i);
        W[i-1].push_back(0);
        E[i].push_back(i-1);
        W[i].push_back(-1); 
    }
    spfa();
    printf("%d",dis[n]);
    return 0;
}

转载于:https://www.cnblogs.com/PotremZ/p/POJ1021_TYVJ1415.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值