zoukankan      html  css  js  c++  java
  • POJ1201 Intervals & TYVJ 1589 西瓜种植 差分约束

    $ ightarrow $ 戳我进TYVJ原题

    西瓜种植

    题目限制

    时间限制 内存限制 评测方式 题目来源
    1000ms 131072KiB 标准比较器 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
    

    $ ightarrow $ 戳我进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;
    }
    
  • 相关阅读:
    oracle客户端plsql设置字符集
    命令导入导出oracle库
    java初级开发一系列的工具安装配置
    docker学习笔记-5.数据共享
    docker学习笔记-4.harbor
    flask学习笔记2
    socket编程学习
    docker学习笔记-3.docker镜像制作
    docker学习笔记-2.docker镜像制作
    docker学习笔记-1.docker基础
  • 原文地址:https://www.cnblogs.com/PotremZ/p/POJ1021_TYVJ1415.html
Copyright © 2011-2022 走看看