程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu - 3916 - Sequence Decomposition

hdu - 3916 - Sequence Decomposition

編輯:C++入門知識

題意:給出一個序列,其實就是一個函數,下標從1開始,把這個函數分解成幾個開關函數G(x, y)的和,分法可以有多種,求各種分法中最小y-x+1的最大值。   ——>>這題,真貪心! 對於:2 2 2  顯然,分解成3個G(1, 3)時最小長度y-x+1 = 3;如果不是,那麼其最小長度一定比3小——可得——兩數相等的時候,應把它們歸到一個G中。 對於:2 4 2 如果第一步將2, 4歸到一個G,而不要後面的2時,將得到2G(1, 2) + 2G(2, 3),此時最小長度為2;如果開始時三個數歸到一個G,那麼得到2G(1, 3) + 2G(2, 2),此時最小長度為1——可得——增大時歸到一個G,減小時不歸到一個G,才能使最小長度最大。 開始時我將輸入的數據存入數組a,對a一次次的a[i]--,一直到所有的a[i] == 0,結果不用說——TLE; 接著,看到對於2 3 3 7 4 1,a[1]到a[4]可以直接-2(左邊第一個最小數2),對於4 4 4  7 4 1,a[1]到a[4]可以直接-3(右邊最大一個 - 右邊的數),用這個方法再來將所有的a[i]減至0,結果一樣——TLE; 可以想到,不能這樣直接將所有的a[i]減至0!!! ——>>最後,考慮G(L, R),用m[R]表示a[L]到a[R]要減的量,掃描一次a,維護m與一個左邊最小數要減的temp就好,有點類似線段樹的下傳機制。 [cpp]   #include <cstdio>   #include <algorithm>   #include <cstring>      using namespace std;      const int maxn = 10000 + 10;      int main()   {       int T, N, i;       long long a[maxn], m[maxn];     //a為輸入數組,m[R]表示a[L]到a[R]要減的量       scanf("%d", &T);       while(T--)       {           scanf("%d", &N);           for(i = 1; i <= N; i++) scanf("%I64d", &a[i]);           a[N+1] = 0;     //最後加個0,好處理           int L = 1, R = 1, temp = 0, minn = 2147483647;      //G(L, R),temp為根據後面確定的a[L]要減的量,minn為結果           memset(m, 0, sizeof(m));           while(L <= N)           {               for(; L <= N; L++)                   if(!(a[L]-temp)) temp -= m[L];      //更新                   else break;     //找到第一個不是0的a[L]               if(L > N) continue;     //完成               if(R < L) R = L;        //有可能的,如2 2 2 3 3               for(; R <= N; R++)                   if(a[R+1] < a[R]-m[R])      //找到右界                   {  www.2cto.com                     minn = min(minn, R-L+1);        //更新                       long long dis = a[R] - m[R] - a[R+1];       //dis個G(L, R)                       dis = min(dis, a[L]-temp);                       m[R] += dis;        //累加增量                       temp += dis;        //更新                       break;                   }           }           printf("%d\n", minn);       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved