Hdu 6188 Duizi and Shunzi【思维+Dp】

351 篇文章 2 订阅

Duizi and Shunzi

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


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
Hint
Case 1(1,2,3)(4,5,6) Case 2(1,2,3)(1,1)(2,2)(3,3) Case 3(2,2)(3,3)(3,3) Case 4(1,2,3)(3,4,5)

题目大意:


给出N张牌,连续的三个数字的三张牌可以组成顺子,相同的两个数字组成对子。

问我们最多可以组成多少顺子和对子。


思路:


赛后百度了一波题解,发现大家都会贪心啊TAT:


①首先我们通过简单分析可以得到结论,如果三个连续的数字如果出现了多次。(222333444),我们一定是要先将其选对子,然后去选顺子。那么直接按照对子先选的顺序去贪心可以吗?显然是不行的,比如1 2 3 3 4 5这种,最优解是2,先选对子答案是1.


②那么如果满足上述条件的话,我们不难分析出,如果我们先将这些连续的出现多次的数先取了对子之后,每个数字作为一个顺子的部分的机会是很少的。我们通过简单分析得知,出现了4次就相当多了,反而多出现的顺子部分肯定要作为对子,所以4次肯定是一个可取的极限高度。


③那么我们设定Dp【i】【j】,表示我们以数字i结尾,并且以数字i结尾出现的顺子个数为j个的最优解。这里j最大取4~5其实就足够了。


那么其状态转移我们分成两种情况去走,一种是有重叠部分的去转移,一种是没有重叠部分去转移:




过程维护一下最优解即可,即ans=max(dp【i】【j】);


时间复杂度O(n*4*4)


Ac代码:

#include <bits/stdc++.h>
typedef long long int LL;
int dp[1050000][5];
int have[1050000];
int max(int x,int y)
{
    if(x>y)return x;
    else return y;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(dp,0,sizeof(dp));
        memset(have,0,sizeof(have));
        for(int i=1;i<=n;i++)
        {
            int x;scanf("%d",&x);
            have[x]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=4;j++)
            {
                for(int k=0;k<=4;k++)
                {
                    if(j==0)
                    dp[i][j]=max(dp[i][j],dp[i-1][k]+have[i]/2);
                    else
                    {
                        if(i-3>=0&&have[i]>=j&&have[i-1]>=j&&have[i-2]>=j)
                        {
                            dp[i][j]=max(dp[i][j],dp[i-3][k]+j+(have[i]-j)/2+(have[i-1]-j)/2+(have[i-2]-j)/2);
                        }
                        if(i-5>=0&&have[i]>=j&&have[i-1]>=j&&have[i-2]-k>=j)
                        {
                            dp[i][j]=max(dp[i][j],dp[i-2][k]+j-(have[i-2]-k)/2+(have[i]-j)/2+(have[i-1]-j)/2+(have[i-2]-j-k)/2);
                        }
                    }
                }
                ans=max(ans,dp[i][j]);
            }
        }
        printf("%d\n",ans);
    }
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值