2、東東請客
(meal.c/.cpp/.pas)
【問題描述】
今天是東東 的生日,他決定請幼兒園小班的n個小朋友吃飯。
小朋友都很奇葩。吃飯前,每個小朋友都要求所在桌的小朋友總數不少於乙個定值,比如說第i個小朋友要求所在桌的人數大於等於ai。
【輸入】
輸入檔名為(meal.in)。
第一行乙個正整數n,表示有n個小朋友。
第二行,n個由空格隔開的正整數,第i個數表示ai。
【輸出】
輸出檔名為(meal.out)。
輸出乙個整數。在滿足所有的小朋友的要求下,需要最多的桌子的數量。資料保證有解。
meal.in
meal.out
2 1 2 2 3
資料範圍與約定
對於20%的資料,n <=10
對於40%的資料,n <=1000
對於60%的資料,n <=10000
對於100%的資料,1 <=n <= 10^6
題解顯然本題是動態規劃題目。
首先對輸入資料從小到大排序。設f[i]表示滿足前i個人所得的最大值。
那麼:f[i]=max( f[j]+1 ) 0<=j<=(i-a[i])
顯然o(n^2) 的演算法是沒有辦法的,想到了優化。正常這種問題是用單調佇列優化即可解決,但是由於(i-a[i])是沒有單調性的(隨著i的增加,a[i]也跟著不降的變化),所以單調佇列就不行了。其實只需要找到區間【0,i-a[i]】的最大值即可。
那麼每次我們在狀態轉移的過程中使用樹樁陣列來維護區間的最大值,就能把時間複雜度降下來,這樣做的時間複雜度為o(n*logn+n*logn)時間上有點緊張。
如果我們用字首最大值來做的話就非常好解決了:
f[i] =smax[ i – a[i] ] + 1;
s[i] =max ( smax[i-1] , f[i] ) ;
這樣演算法的時間複雜度為o(n*logn+n),如果使用基數排序,總的時間複雜度降為o(n).
答案1#include
#include
#include
#include
#define m 1000100
using namespace std;
int n,tot,a[m],f[m],s[m],t[m];
int main()
for(int i=1;i<=n;i++)
while(t[i])
a[++tot]=i,t[i]--;
for(int x,i=1;i<=n;i++)
cout<
fclose(stdin);
fclose(stdout);
return 0;
}答案2
#include
#define m 1000100
using namespace std;
int n,a[m],f[m],s[m],t[m];
void fix(int x,int d)
int main()
cout<
fclose(stdin);
fclose(stdout);
return 0;
}
2010 遼寧省賽
1.dinner 題目大意 給你乙個數n,後有n個字串,問字串中是否含有bowl,knife,fork and chopsticks.這四個單詞,如果存在就輸出。include includechar s 4 30 char a 30 int main void join int u,int v i...
2010遼寧省賽F(字典樹,動態規劃)
include using namespace std int n,x char s 10010 char a 31010 int val 100010 int ch 100010 30 int dp 100010 int main u ch u a j a val u max val u x u為...
淨誤差與遺漏為負值的含義 遼寧省淨水箱
遼寧省淨水箱,湖南昊道環境團隊實力強,讓您的管道清潔如新,清除十幾年積累的隱患。遼寧省淨水箱,對廢氣進行吸附濃縮 淨化後可直接排放。廠家直銷 淨化過濾棉 迴圈塔 淨水塔 迴圈利用淨化棉網 黑色淨棉 資訊由發布人自行提供,其真實性 合法性由發布人負責。前期可適當作些宣傳。該專案是專為燒淨液化氣鋼瓶裡的...