1. 程式人生 > >Codeforces Round #523 (Div. 2) B Views Matter

Codeforces Round #523 (Div. 2) B Views Matter

傳送門

https://www.cnblogs.com/violet-acmer/p/10005351.html

 

這是一道貪心題麼????

題意:

  某展覽館展覽一個物品,此物品有n堆,第 i 堆有a[ i ]個正方塊,問最多可以去除多少個正方塊,使得其俯檢視與右檢視的保持不變。

  並且去除某正方塊a下方的正方塊時,是不會導致a方塊下降的(無重力)。

題解:

  相關變數解釋:

1 int n,m;
2 ll sum;//所有的方塊
3 int a[maxn];//a[i] : 第i堆有a[i]個正方塊
4 int index;//來到第index堆物品
5 int maxHigh;//
當前保留下來的正方塊的最大高度 6 int remain;//必須保留下的正方塊個數

  單純的解釋,貌似,不太會,那就用個樣例解釋吧,哈哈哈。

  例如: 

1 Input
2 10 17
3 12 16 6 9 12 6 12 1 12 13
4 
5 Output
6 83

  首先,將a[ ]陣列按照從小到大的規則排序,排好序後,配圖如下:

                   

  大體思路是:

    (1):從第一堆物品開始遍歷,定義變數h=a[ i ]-maxHigh,根據maxHigh的定義可知,在第一堆物品之前,是沒有方塊的,所以,初始化maxHigh=0,那麼h代表的就是

    當前堆需要保留的最多的方塊數,定義變數len=n-index+1,index表示的是當前來到第index堆,那麼len就表示在這之後還有多少堆。

    (2):判斷是否可以組成h*h的大正方形,也就是判斷len是否大於等於h:

      ①如果可以,例如圖片中的紅方框,如果可以,那麼h*h的正方形上的對角線上的方塊是一定要保留的,且是當前正方形需要保留的最少的方塊數。

      ②反之,len*len的正方形最少需要保留的方塊個數也是其對角線的方塊個數。

    (3):當index > n 時,判斷maxHigh是否達到了最大高度a[n],如果沒有,還需額外保留a[n]-maxHigh個正方塊。

具體細節看程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 #define ll long long
 6 const int maxn=1e5+10;
 7 
 8 int n,m;
 9 ll sum;
10 int a[maxn];
11 
12 ll Solve()
13 {
14     sort(a+1,a+n+1);
15     if(n == 1)
16         return 0;
17     ll remain=0;
18     int index=1,maxHigh=0;
19     while(index <= n)
20     {
21         int h=a[index]-maxHigh;
22         int len=n-index+1;
23         if(len >= h)//可以形成h*h的正方形
24         {
25             //注意需要特判h == 0的情況
26             remain += (h == 0 ? 1:h);//需要保留的最少的方塊數為h個
27             index += (h == 0 ? 1:h);//[index,index+h]已經保留過正方塊了,直接來到index+h堆
28             maxHigh += h;//更新前index堆達到的最大高度
29         }
30         else//可以形成len*len的正方形
31         {
32             remain += len;
33             index += len;
34             maxHigh += len;
35         }
36     }
37     remain += (a[n]-maxHigh);//步驟(3)
38     return sum-remain;
39 }
40 
41 int main()
42 {
43     cin>>n>>m;
44     for(int i=1;i <= n;++i)
45         cin>>a[i],sum += a[i];
46     cout<<Solve();
47 }
View Code