汕头市赛srm10 T2

n个数,分组,数Ai要在至少含有Ai个数的组,求最多分多少组。

方法一:大的数应该尽量跟大的在一起,这样才能让小的出现很多很多组,所以从大到小排序,给当前序列中最大的数x分x个数。代码如下:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 //#include<iostream>
 6 using namespace std;
 7 
 8 int n;
 9 #define maxn 1000011
10 int a[maxn];
11 bool cmp(const int &a,const int &b) {return a>b;}
12 int main()
13 {
14     scanf("%d",&n);
15     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
16     sort(a+1,a+1+n,cmp);
17     int ans=0,i;
18     for (i=1;i<=n;i+=a[i]) ans++;
19     if (i>n+1) ans--;
20     printf("%d\n",ans);
21     return 0;
22 }
View Code

错误!“最大的数尽量跟大的在一起”不等于"给最大的数x分x个数“,有时一个大数可以多容纳一点大数来满足更多的小数组。有反例(TJM大爷提供)1 1 1 3 3 3 3,答案4,错误答案3。

方法二:贪心不行就dp。先把数从小到大排序,f[i]--前i个数分组最多,f[i]=max(f[j])+1,j∈[1,i-a[i]],重复地访问前缀最大可另开数组统计。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 //#include<iostream>
 6 using namespace std;
 7 
 8 int n;
 9 #define maxn 1000011
10 int a[maxn],f[maxn],Max[maxn];
11 int main()
12 {
13     scanf("%d",&n);
14     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
15     sort(a+1,a+1+n);
16     f[0]=Max[0]=0;
17     for (int i=1;i<=n;i++)
18     {
19         if (i-a[i]>=0)
20             f[i]=Max[i-a[i]]+1;
21         else f[i]=0;
22         Max[i]=max(Max[i-1],f[i]);
23     }
24     printf("%d\n",f[n]);
25     return 0;
26 }
View Code

 

posted @ 2017-08-07 20:08  Blue233333  阅读(121)  评论(0编辑  收藏  举报