題目描述
給定n 個選手,將他們分成若干只隊伍。其中第i 個選手要求自己所屬的隊伍的人數大等於a[i]人。
在滿足所有選手的要求的前提下,最大化隊伍的總數。
注:每個選手屬於且僅屬於一支隊伍。
輸入格式
第一行乙個整數n,表示人數。
以下n 行,每行乙個整數表示a[i]。
輸出格式
輸出隊伍總數的最大值。資料保證有解。
樣例輸入52
1223
樣例輸出2
資料範圍
對於20%的資料,n <= 10
對於40%的資料,n <= 1000
對於60%的資料,n <= 10000
對於100%的資料,1 <= n <= 10^6
solution:
最開始想到貪心。
先把a[ i ] 排序。
然後我們從大到小依次加入隊伍就好了。
3 2 2 2 1
先把 3 2 2 加入
再把 2 1 加入 就可以了。
但是實際上這東西是錯的。 例子
3 3 3 3 2 2 1
變成 3 3 3。3 2 1。
實際上可以 1 。2 2。3 3 3 3
所以貪心有問題。
考慮dp
f[i] 表示前 i 個人可以最多分成的隊伍數目。
顯然 如果第 i 個人對隊伍數目做出貢獻,當且僅當 滿足了 第i個人的要求 a[i]
所以 f [ i ] =max +1 其中 0 < k < = i - a[ i ]
所以 可以維護 乙個 最大值 g [ k ] 表示 f[ 1..k ] 的 最大值。
每次修改 了 f [ i ] 的話 就是 g [ i ] =max
這就避免了每次查詢 max f [ k ] 都要從 頭 到 i- a [ i ] 掃瞄一遍。
所以時間複雜度 為 o(n)
#include#include#include#includeusing namespace std;
const int maxn=1e6+5,inf=x3f3f3f3f;
inline void _read(int &x)
for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
if(!sign)x=-x;
}int n,f[maxn],s[maxn],g[maxn];
int main()
cout<
NKOJ 3860 分隊問題(DP 字首和優化)
問題描述 給定 n 個選手,將他們分成若干只隊伍。其中第 i 個選手要求自己所屬的隊 伍的人數大等於 a i 人。在滿足所有選手的要求的前提下,最大化隊伍的總數。注 每個選手屬於且僅屬於一支隊伍。輸入格式 第一行乙個整數 n,表示人數。以下 n 行,每行乙個整數表示 a i 輸出格式 輸出隊伍總數的...
洛谷P2062 分隊問題
題目鏈結 一道容易想岔的題.一開始用了貪心的方法先排序後從末尾開始掃瞄陣列.idx的移動規則 移動到i a i 的位置直到將要越界為止.這個思路是有漏洞的,比如說下面這組資料 5 3 3 3 3 3 1 1 這麼貪心輸出的答案是2其實正確的答案是3.因為我們把最後乙個3歸入到第一組裡得到的答案會更好...
記爬蟲小分隊(六)
import requests from bs4 import beautifulsoup start url response requests.get start url,headers headers text soup beautifulsoup response,html.parser i...