HDU 6188 Duizi and Shunzi(贪心+细节)

来源:互联网 发布:借贷软件排行 编辑:程序博客网 时间:2024/06/12 01:23

题目地址
题意:给你一堆牌,有两种组合方式,问最多能组合成多少个对子和顺子(同牌面的2张可以组成一个对子,连续牌面数字的3张可以组成一个顺子)
思路:这题是贪心写的,我昨天虽然想到了这种方法,但是因为急并且思路比较混乱导致一直在wa我就没写了,今天重新理清了一下思路。这题的贪心思想是:我们存下每个牌面有多少张,然后从前到后去判断,当这个牌面有大于等于2张的时候,无论如何先组成对子,因为对子的代价比顺子少1张,然后就开始考虑顺子了,如果当前的牌还剩一张,并且后面一位牌面的牌数为奇数,后面两位的牌面有牌的话,就可以组成一张顺子,有人会想为什么后面两位的牌面有牌的话就直接不管是不是奇数就直接组成顺子了,你可以这样想,因为下一位的牌数为奇数,就说明组成对子后又会剩一张牌,那如果第三位的牌是奇数的,那就正好加上了一张,如果第三位的牌是偶数的,那就没有加上一张当时,因为是只需要1张牌,所以就多出了一张可以与后面组成顺子的牌了,这样的话就不是最大化了吗,因为要不是持平要不是增加了。

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 1000010#define M 1000000#define Q 300010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;int num;int flag[N];int main() {    cin.sync_with_stdio(false);    int n;    while (cin >> n) {        memset(flag, 0, sizeof(flag));        for (int i = 0; i<n; i++) {            cin >> num;            flag[num]++;        }        int ans = 0;        for (int i = 1; i <= M; i++) {            if (flag[i] >= 2) {                ans += flag[i] / 2;                flag[i] %= 2;            }            if (flag[i] && flag[i + 1] % 2 == 1 && flag[i + 2]) {                ans++;                flag[i]--;                flag[i + 1]--;                flag[i + 2]--;            }        }        cout << ans << endl;    }    return 0;}
原创粉丝点击