zoukankan      html  css  js  c++  java
  • 生日礼物(我的思维崩盘题- -.)

    个人心得:做完这题发现自己有多水,先是思路崩盘,后面借鉴思路之后再试,编程崩盘。好吧,全程崩盘,我要很无奈。

    总的来说,还是自己思维的不严谨性和不会更好的模拟和运用学过的知识,还是有待进步!

    好吧先看这道令我奔溃的题吧,可能是我太水了!!!

    小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。Input第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。Output应包含一行,为最短彩带长度。Sample Input

    6 3
    1 5
    2 1 7
    3 1 3 8

    Sample Output

    3

    Hint

    有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。
    【数据规模】
    对于50%的数据, N≤10000;
    对于80%的数据, N≤800000;
    对于100%的数据,1≤N≤1000000,1≤K≤60,0≤彩珠位置<2^31。

    做题思路:本来是想从上到下一直延伸的,发现实施不了,后想着每个来一次深搜,绝对超时,后面看了网上的思路。很令人佩服。

    【分析】:
              这道题用贪心的思想。贪心的方法为:对于每种颜色的彩珠,从编号小的地方往后推进,用数组where[x]记录x颜色的珠子已经推进到了哪个地方。首先,在所有颜色当前推进位置中,选出位置编号的最大值max1和最小值min1,很容易想到当前符合题意的长度就是max1-min1<如图一>,这一步是计算。
              然后尝试将某个满足下面条件的颜色的where向后推一位:这一颜色的当前推进位置是所有颜色中最小的,且它的后面那一位最小,这一步是转移<如图二>。
              现在来计算循环次数:有N个珠子,K种颜色,转移需转移N-K次,计算需计算N-K+1次<多的“1”是在初始位置时需要进行一次计算>,因此循环次数为N-K+1。这道题贪心之处就在于每次转移最小值,这样保证情况最优且考虑全面。
    【时间复杂度分析】:
              循环次数*(转移+计算):O((N-K+1)*2*K)=O(N*K)
    个人心得:挺不错的思想,可是实施起来比较麻烦,每次选最小的,后面看到其他的大神用了优先队列发现挺完美,不过终止条件和结构体的建立要思考,结构体必须包括他所属的颜色和在的位置,答案的代码是直接建立最大数据的结构体数组,一个颜色标志,一个存储位置,还有个就是存储下一个同等颜色的位置,
    我发现BZOJ的水题都比较高档昂。这道题的基本思想是,每次用优先队列把位置最靠前的颜色弹出来,并把与它颜色相同的下一个点的位置进队列,每次更新最优长度。

        1.初始化:每个点的下一个相同颜色点的位置。

        2.将每个颜色的第一个点入队列,算第一个状态。

        3.每次将队列最前端的颜色弹出,将他的下一个点放入队列,更新最优长度。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<utility>
     6 #include<queue>
     7 #define MAXN 1000010
     8 #define INF (1<<30)
     9 using namespace std;
    10 int t[61],s[61];
    11 struct node{
    12     int first;
    13     int second;
    14     int next;
    15     node(){};
    16     void init(int x,int y,int z){
    17         first=x;
    18         second=y;
    19         next=z;
    20     }
    21     friend bool operator < (node a,node b){
    22         return a.second>b.second;
    23     }
    24 }x[MAXN];
    25 priority_queue<node> q;
    26 int main(){
    27     s[0]=0;
    28     int n,k,l,r=0;
    29     scanf("%d%d",&n,&k);
    30     for(int i=1;i<=k;i++){
    31         scanf("%d",&s[i]);
    32         s[i]=s[i]+s[i-1];
    33         for(int j=s[i-1]+1;j<=s[i];j++) {
    34             int a;
    35             scanf("%d",&a);
    36             x[j].init(i,a,j+1);
    37         }
    38     }
    39     for(int i=0;i<k;i++) {
    40         r=max(r,x[s[i]+1].second);
    41         q.push(x[s[i]+1]);
    42     }
    43     int ans=r-q.top().second;
    44     while(1){
    45         node tmp=q.top();
    46         q.pop();
    47         if(tmp.next-1<s[tmp.first]) {
    48             r=max(x[tmp.next].second,r);
    49             q.push(x[tmp.next]);
    50         }
    51         else break;
    52         tmp=q.top();
    53         ans=min(r-tmp.second,ans);
    54     }
    55     printf("%d",ans);
    56     return 0;
    57 }
  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/blvt/p/7263997.html
Copyright © 2011-2022 走看看