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

    1303 最小覆盖  

      题目的大概意思:给一组线段[Li, Ri],Li, Ri都是整数,在这组线段中找出数量最少的线段使这些线段能完全覆盖[0,M]。

      输入:

      第一行整数M (1 ≤ M ≤ 5000)。

      后面是整数对,每对Li, Ri(abs(Li), abs(Ri) ≤ 50000)占一行。最后一行为0 0表示结束。

      输出:

      第一行打印完全覆盖[0,M]的最小线段数。

      后面打印覆盖[0,M]的线段,格式和输入一样。

      如果不存在完全覆盖则打印“No solution

      思路:尽量选择覆盖[0,M]长的线段,这也是很明显的,线段覆盖[0,M]越长,完全覆盖[0,M]所需要的线段数必然越少,所以这道题目可以使用贪心尽量选择覆盖[0,M]越长的线段,当然也可以用dp,只是效率差些。dp[k]表示完全覆盖[0,M]的最少线段数,dp[k] = dp[kk] + 1 ,其中kk满足min(0 <= kk < k, [kk, x], x >= k),我的策略是kk在满足(0 <= kk < k, [kk, x], x >= k)的条件下尽量选择最小的kk,这样覆盖[0,M]就会越长。另外一个贪心选择是对于输入,如果线段的左端点相同,只考虑线段长度最长的那个。还有就是对输入的处理,由于线段的两个端点可以是负数和超过5000,所以对于两个端点都是不超过0的数或者都是不小于M的数的线段都直接不予考虑,然后就是线段的左端点为负数的情况,一律将其看做左端点为0.

      代码:

    #include <stdio.h>
    
    typedef struct _pair
    {
        int l;
        int r;
        int flag;
    }pair_t;
    pair_t segment[5001];
    int dp[5001];
    int path[5001];
    int m;
    
    void print(int n)
    {
        if (n == -1)
            return;
        print(path[n]);
        printf("%d %d\n", segment[n].l, segment[n].r);
    }
    int main ( int argc, char *argv[] )
    {
        int l, r;
        int i, j;
        int flag;
    
        scanf("%d", &m);
        while (1)
        {
            scanf("%d%d", &l, &r);    
            if (l == 0 &&  r == 0)
                break;
            if (l < 0 && r >= 0)    
            {
                if (segment[0].r < r)   //当左端点相同时,选择线段更长的 
                {
                    segment[0].l = l;
                    segment[0].r = r;
                    segment[0].flag = 1;
                }
            }
            else if (l >= 0 && l <= m)  
            {
                if (segment[l].r < r)    
                {
                    segment[l].l = l;
                    segment[l].r = r;
                    segment[l].flag = 1;
                }
            }
        }
        path[0] = -1;
        flag = 0;
        for (i = 1; i <= m; i ++)
        {
            for (j = 0; j <= i; j ++)
                if (segment[j].flag && segment[j].r >= i)
                {
                    if (j == 0 || dp[j])    
                    {
                        dp[i] = dp[j] + 1;
                        path[i] = j;
                    }
                    else
                        flag = 1;
                    break;
                }
            if (j > i || flag)
                break;
        }
        if (i <= m)
            printf("No solution\n");
        else
        {
            printf("%d\n", dp[m]);
            print(path[m]);
        }
        return 0;
    }                /* ----------  end of function main  ---------- */
  • 相关阅读:
    ASE19团队项目 beta阶段 model组 scrum report list
    ASE19团队项目 beta阶段 model组 scrum7 记录
    ASE19团队项目 beta阶段 model组 scrum6 记录
    ASE19团队项目 beta阶段 model组 scrum5 记录
    ASE19团队项目 beta阶段 model组 scrum4 记录
    ASE19团队项目 beta阶段 model组 scrum3 记录
    ASE19团队项目 beta阶段 model组 scrum2 记录
    ASE19团队项目 beta阶段 model组 scrum1 记录
    【ASE模型组】Hint::neural 模型与case study
    【ASE高级软件工程】第二次结对作业
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/3080454.html
Copyright © 2011-2022 走看看