樂團派對
阿新 • • 發佈:2021-01-13
技術標籤:補題
連結:https://ac.nowcoder.com/acm/contest/6874/B
來源:牛客網
題目描述
音樂是帶給大家快樂的存在,而你的目標就是組建若干支樂隊,讓世界聽到你們的演奏!
你目前有nn位樂手,每位樂手只能進入一個樂隊,但並不是每位樂手都能擔大任,因此需要團隊合作。第ii位樂手的能力值為a[i]a[i],表示該位樂手所在樂隊的人數必須大於等於a[i]a[i]。在保證每位樂手都被分進一個樂隊的情況下,樂隊數量最多可以是多少?
輸入描述:
第一行一個正整數nn,表示樂手人數,n\leq10^{5}n≤10
5
。
第二行nn個正整數a[i]a[i],表示每位樂手的能力值,a[i]\leq10^{9}a[i]≤10
。
輸出描述:
輸出最多的樂隊數量。若無法保證每位樂手都被分進一個樂隊,則輸出-1。
示例1
輸入
複製
4
2 1 2 1
輸出
複製
3
第一種貪心做法:
先對每個人的能力值排序
先把後面的人先安排了,給最後一個人安排一個隊伍
然後從前到後列舉每個人
給每個人安排一個隊伍,如果隊伍的人數比能力小的話,就向後走那個差的步數,走過去後的那個人的能力又是最大的,如果能裡再小於人數的話,再接著往後走,要麼走到把能用的人用完依然存在能力小於人數的話,就把這些人放到最後的隊伍,否則的話就加上這個隊伍。接著往後列舉
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <set>
using namespace std;
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =1e5 + 10;
const int M = 2e5 + 10;
const int Mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int P = 13331;
int n;
string str;
int a[N];
int f[N];
int main(){
// freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
int cnt = 1;
int ren = 1;
sort(a + 1, a + 1 + n);
if(a[n] > n){
printf("-1");
return 0;
}
for (int i = 1; i <= (n - a[n]); i ++){
while(i <= (n - a[n]) && ren < a[i]){
int temp = (a[i] - ren);
ren += (temp);
i += (temp);
}
if (i > (n - a[n])) break;
cnt ++;
ren = 1;
}
cout << cnt << endl;
return 0;
}
我們發現當列舉到每個人的時候,有兩種可能,要麼他和前一個人一個隊伍,要麼給他新安排一個隊伍,安排的時候從他前面找(a[i])個人,所以我們很自然地想到了動態規劃,但是需要我們注意的是把這個人安排到到前一個人不一定是成立的,因為有可能當前這個人的能力比錢一個人的能力大得多
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <set>
using namespace std;
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =1e5 + 10;
const int M = 2e5 + 10;
const int Mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int P = 13331;
int n;
string str;
int a[N];
int f[N];
int main(){
// freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
// LL ans = 0;
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
if (a[n] > n){
cout << "-1" << endl;
return 0;
}
else{
for (int i = 1; i <= n; i ++){
if (i - a[i] >= 0) f[i] = max(f[i], f[i - a[i]] + 1);
if (i != n) f[i] = max(f[i - 1], f[i]);
}
cout << f[n] << endl;
}
return 0;
}