hdu 6188 Duizi and Shunzi

Duizi and Shunzi

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 73    Accepted Submission(s): 30


Problem Description
Nike likes playing cards and makes a problem of it.

Now give you n integers, ai(1in)

We define two identical numbers (eg: 2,2) a Duizi,
and three consecutive positive integers (eg: 2,3,4) a Shunzi.

Now you want to use these integers to form Shunzi and Duizi as many as possible.

Let s be the total number of the Shunzi and the Duizi you formed.

Try to calculate max(s).

Each number can be used only once.
 
Input
The input contains several test cases.

For each test case, the first line contains one integer n(1n106). 
Then the next line contains n space-separated integers ai (1ain)
 
Output
For each test case, output the answer in a line.
 
Sample Input
7 1 2 3 4 5 6 7 9 1 1 1 2 2 2 3 3 3 6 2 2 3 3 3 3 6 1 2 3 3 4 5
 
Sample Output
2 4 3 2
 
贪心搞一下。
首先,在一般的情况下,我们优先考虑取对子(因为对子只消耗两张牌)。这样我们可以把每种牌的数量变为1或者2(先取好对子)。
之后有四种情况:
(a)连续的三张牌的数量都为2,这三张牌都取对子为最优。
(b)连续的两张牌的数量都为2,我们也取对子,为了让后面能够更多的牌可选(比如1 2 2 3 3 4 5 6 这种情况,我们如果1 2 2 3 3 4取顺子的话 后续的5 6就组不了顺子了)
(c)单独的一张牌的数量为2,我们想前看(因为依次遍历过来,前面的都是最优情况了),如果能够取到顺子,优先取顺子,取不到顺子,就自己成一个对子。
(d)牌的数量为1的时候,遍历的反向去顺子,能取就取。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define mt(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
int a[1000001];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        mt(a);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            a[x]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>2)
            {
                if(a[i]%2==0)
                {
                    ans+=(a[i]-2)/2;
                    a[i]=2;
                }
                else
                {
                    ans+=a[i]/2;
                    a[i]=1;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]==2)
            {
                if(i+1<=n && a[i+1]==2)
                {
                    if(i+2<=n && a[i+2]==2) // (a)
                    {
                        a[i]=a[i+1]=a[i+2]=0;
                        ans+=3;
                    }
                    else // (b)
                    {
                        a[i]=a[i+1]=0;
                        ans+=2;
                    }
                }
                else
                {
                   if(i-1>=1 && i-2 >=1 && a[i-1] && a[i-2]) // (c)
                   {
                       a[i-1]--;
                       a[i-2]--;
                       a[i]--;
                       ans++;
                   }
                   else
                   {
                       a[i]=0;
                       ans++;
                   }
                }
            }
            else if(a[i]==1) //(d)
            {
                if(i-1>=1 && i-2>=1 && a[i-1]>=1 && a[i-2]>=1 )
                {
                    a[i-1]--;//
                    a[i-2]--;//
                    a[i]--;//
                    ans++;//
                }
            }
        }
        cout<<ans<<endl;
    }
}
原文地址:https://www.cnblogs.com/z1141000271/p/7459946.html