zoukankan      html  css  js  c++  java
  • POJ1716 贪心

    题目大意:在[0,10000]上给出n个区间,要求在区间选整数点,每个区间至少包含两个点,问至少要几个点。题目保证有解决方案。

    题目分析:

      我们做过在区间上至少包含一个点的题目。类似的方法,我们先排序后去掉区间包含的情况。接着我们贪心。对于第i个区间,取最后两个点,如果第i+1个区间包含这两个点,那么跳到第i+2个区间。如果第i+1个区间一个点也不包括,那么对于第i+1个区间取最后两个点。如果只包含一个点,那么在第i+1个区间取最后一个点,继续判断。

    题目代码:

      

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #include<algorithm>
     8 using namespace std;
     9 
    10 struct edge{int to,w;};
    11 
    12 int n;
    13 vector <edge> g[10200];
    14 int d[10200];
    15 queue<int> que;
    16 int maxx;
    17 
    18 void read(){
    19     for(int i=0;i<=10001;i++) g[i].clear();
    20     maxx = -1200;
    21     for(int i=1;i<=n;i++){
    22         int x,y; scanf("%d%d",&x,&y);
    23         maxx = max(maxx,y+1);
    24         x++;y++;
    25         edge ed;ed.to = y;ed.w = 2;
    26         g[x-1].push_back(ed);
    27     }
    28     for(int i=0;i<=maxx;i++){
    29         edge ed;ed.to=i+1;ed.w=0;
    30         g[i].push_back(ed);
    31         ed.to=i;ed.w=-1;
    32         g[i+1].push_back(ed);
    33     }
    34 }
    35 
    36 void work(){
    37     for(int i=1;i<=maxx;i++) d[i]=-1;
    38     que.push(0);
    39     d[0] = 0;
    40     while(!que.empty()){
    41         int k = que.front();que.pop(); 
    42         for(int i=0;i<g[k].size();i++){
    43             if(g[k][i].w+d[k] > d[g[k][i].to]){
    44                 d[g[k][i].to] = g[k][i].w + d[k];
    45                 que.push(g[k][i].to);
    46             }
    47         }
    48     }
    49     printf("%d
    ",d[maxx]);
    50 }
    51 
    52 int main(){
    53     scanf("%d",&n);
    54     read();
    55     work();
    56     return 0;
    57 }

    思考:我们不妨对问题加以拓展。

      问题一:我们做过一个区间选一个点的题,做过一个区间选两个点的题。那么当一个区间选n个点时怎么去做?

      问题二:上面的区间选点数量都是相同的,当区间选点数量不同时怎么做?

    解法:

      对于问题一:很容易就能想出拓展方法,每次对每个区间都选最后n个点,容易证明这是最优的。

      对于问题二:发现上面的贪心无法使用,需要另辟蹊径。不妨令s[i]表示前i个点被选的情况。那么有s[r]-s[l-1]>=c[i]。c[i]该区间应选点数。

            由于这里有很多个不等式,又要求最小化s[10000],容易思考到这可能是要用到线性规划去解决。

            接着我们打了一个单纯形法。

            

            收获了一个TLE。仔细想想就会发现问题并不是这么难。这里的不等式并不如线性规划里面的那么复杂。

            那么我们可以建图跑最长路。这就是答案。具体怎么建图可以参考网上其它人的博客。我不想再写下去了。

  • 相关阅读:
    tp5 -- 微信公众号支付
    tp5对接支付宝支付简单集成
    tp5 -- 腾讯云cos简单使用
    PHP 递归无限极下级
    PHP 头部utf-8
    ThinkPHP5.0-多语言切换
    MySQL插入SQL语句后在phpmyadmin中注释显示乱码
    C#中练级orcle数据查询
    sql中递归查询
    sql server数据类型与其他数据库数据类型对应关系
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/7608044.html
Copyright © 2011-2022 走看看