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。仔细想想就会发现问题并不是这么难。这里的不等式并不如线性规划里面的那么复杂。

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

  • 相关阅读:
    屏蔽打开文件时提示“您尝试打开的文件xxx.xls的格式与文件扩展名指定的格式不一致。打开文件前请验证文件没有损坏且来源可信。是否立即打开该文 件?”
    sql实现MD5加密
    微信小程序在苹果手机的New Date坑
    命令行同步互联网时钟
    excel怎么把单元格内某个字标红,其他字不变
    js 字符串排序 String.prototype.localeCompare
    vscode 使用键盘运行 npm命令
    vscode 使用键盘打开 git分支面板
    给img标签的src属性使用file文件对象
    DOM0级 与 DOM2级
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/7608044.html
Copyright © 2011-2022 走看看