• 汕头市赛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
    ",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
    ",f[n]);
    25     return 0;
    26 }
    View Code
  • 相关阅读:
    linux源码阅读笔记 asm函数
    linux源码阅读笔记 #define 语句的妙用
    对于python的内存管理的好文章
    #define x do{......} while(0)的用处
    reverse list
    判断数组是否存在重复元素
    找出数组中出现奇数次的元素
    找出数组中唯一的重复元素
    两个有序数组中的交集
    Java Socket(3): NIO
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7301075.html
Copyright © 2020-2023  润新知