傳送門ios
思路:「Dreamoon will choose a number pipi from range [1,n−li+1](inclusive) and will paint all cells from pipi to pi+li−1(inclusive) in ii-th color.」能夠知道從[1, n - li - 1]任意位置日後染pi個格子爲第ith種顏色。spa
容易想到,若是∑li < n,說明"-1"。code
若是∑li>=n,由於咱們不知道怎麼染色纔好,但咱們知道SUM = ∑li,即咱們目前還能夠染色SUM塊。不如咱們類貪心的思想染色,這樣咱們能夠分紅兩種狀況:xml
假設now爲當前的pi,len爲剩餘未染色的塊blog
①SUM - now >= len - 1get
說明咱們只用當前顏色染色1塊,以後SUM-now的個數也能夠染色剩餘的部分,那麼 SUM -= now ,len -= 1string
②SUM - now < len - 1it
說明咱們若是用當前顏色只染色1塊,則SUM - now 不能染色剩餘的 len - 1,那麼咱們須要讓io
SUM - now == len - 1 - ? (==>) ? = (len - 1) - (SUM - now),則當前顏色須要染色 ? + 1個才行。SUM -= now, len -= (1 + ?)function
這樣咱們能夠用pre_s,pre_d記錄以前的開始位置和染色長度。
固然咱們不能忘記一個條件「每種顏色只能在[1, n - li - 1]開始日後染色」,若是(n - li - 1) < pre_s + pre_d,
說明咱們沒法完成知足題意的染色,由於咱們前面是儘量少的染色且知足題目要求,若是仍然沒法知足,說明沒有可行解。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <vector> 8 #include <cstring> 9 #include <functional> 10 #define LL long long 11 using namespace std; 12 13 const int N = 1e5 + 10; 14 int L[N], inx[N]; 15 16 void solve () 17 { 18 int n, m, len; 19 scanf("%d%d", &n, &m); 20 21 LL Sum_d = 0; 22 for(int i = 1; i <= m; ++i) { 23 scanf("%d", L + i); 24 Sum_d += L[i]; 25 } 26 27 int pre_s, pre_d; 28 pre_s = 1; pre_d = 0; 29 len = n; 30 for(int i = 1; i <= m; ++i) { 31 //printf("start = %d L = %d\n", pre_s + pre_d, n - L[i] + 1); 32 if(n - L[i] + 1 < pre_s + pre_d) { break; } 33 34 if(Sum_d - L[i] >= len - 1) { 35 Sum_d -= L[i]; 36 len -= 1; 37 pre_s = pre_s + pre_d; 38 pre_d = 1; 39 } else { 40 int tmp_d = (len - 1) - (Sum_d - L[i]); 41 if(tmp_d + 1 > L[i]) { break; } 42 Sum_d -= L[i]; 43 len -= (1 + tmp_d); 44 pre_s = pre_s + pre_d; 45 pre_d = (1 + tmp_d); 46 } 47 inx[i] = pre_s; 48 } 49 50 // cout << "len = " << len << endl; 51 52 if(len > 0) { 53 printf("-1\n"); 54 } else{ 55 for(int i = 1; i <= m; ++i) { printf("%d ", inx[i]); } 56 printf("\n"); 57 } 58 59 60 } 61 62 int main() 63 { 64 solve(); 65 66 return 0; 67 }