【贪心】hdu

来源:互联网 发布:淘宝开店咋样实名认证 编辑:程序博客网 时间:2024/05/22 22:27

Problem Description

输入一个n,接下来有n个数,让你求出能组成最多的对子或者顺子的和。
对子: (2,2),顺子: (1,2,3)。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188

思路:

从小跑到大。例如1,1,2,3。跑到1的时候有对子,这时候优先要对子。不然你牺牲对子去换顺子,也就是一比一,根本不会赚。例如1,2,2,3。这个思路和前面一样,如果2,2拆开当顺子不会赚。例如1,2,3,3这时候跑1。发现1还有一张,2的个数是奇数,这时候就可以选择顺子1,2,3,因为3是最后面的。拆开它,一比一,不亏。它可能会和后面的5,6形成顺子,这时候就赚了。所以贪心的大体思路是这样,详细的看代码。

#include<cstdio>#include<cstring>using namespace std;#define N 1000055int vis[N];int main(){    int n, i, num;    while(~scanf("%d", &n))    {        memset(vis, 0, sizeof(vis));        for(i = 0; i < n; i++)        {            scanf("%d", &num);            vis[num]++;//这里我用的是下标存数,也就是桶        }        int ans = 0;        for(i = 1; i <= 1000000; i++)//从小跑到大        {            if(vis[i] >= 2)//第一个数如果有对子。那么优先对子            {                ans += vis[i] / 2;                vis[i] = vis[i] % 2;            }            if(i <= 999998)//如果第一个数是1,第二个数是奇数个,那么组成顺子            {                if(vis[i + 2] && vis[i] == 1 && vis[i + 1] % 2!=0 ) {                ans++;                vis[i]--; vis[i+1]--; vis[i+2]--;}            }        }        printf("%d\n", ans);//输出    }}
原创粉丝点击