NYOJ 2358(可能不存在的题-多校脸萌六)LLM找对象-dp

题目描述

找对象可不是一件容易的事情,如果你想找个好对象啊,喜欢打游戏的得把游戏戒了,喜欢acm的得把acm戒了,然后“天将降女朋友于斯人也,必先看其有没有穿拖鞋”,现在LLM相中了N个妹子,他通过观星、占卜、杀队友祭天等方法终于发现了自己与这N个妹子分别

相遇的时间,但是LLM还是想穿拖鞋(但是穿了拖鞋就会情商急速下降找无法认识妹子),因此LLM决定忍痛割爱选择K天不穿拖鞋,但是不可以有任意两天连续不穿拖鞋,现在LLM问你他最多可以认识多少妹子

输入

每个测试文件包含不多于10组测试样例

每个测试样例第一行包含两个整数,N,K

接下来一行有N个数字,分别代表和第i个妹子相遇的是哪一天(这一天的编号小于100000000)

1<=N<=500,1<=K<=100000000

输出

输出包含一行,代表可以认识的妹子数量

样例输入

5 2
666 233 10086 233 10086

样例输出

4
开始我也不会写,然后被一位大佬教导(LYH),总算朦胧懂些,还是我too young,放下大佬的代码,注释很清晰易懂。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define me(a, b) memset(a, b, sizeof(a))
int a[1010], b[1010];
int dp[1010][1010][2];//i为当前天数,j为从第一天到第i天不穿拖鞋的总天数,k=0,今天穿拖鞋,k=1,今天不穿拖鞋
int main()
{
    int n, k, i, j;
    while(~scanf("%d %d",&n,&k))
    {
        for(i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        sort(a+1, a+n+1);
        int count = -1;
        a[0] = -1;
        me(b, 0);
        for(i = 1; i <= n; i++)
        {
            if(a[i] != a[i-1])
            {
                if(a[i] > a[i-1] + 1)
                {
                    count += 2;
                    b[count] = 1;
                    b[count-1] = 0;
                }
                else
                {
                    count++;
                    b[count] = 1;
                }
            }
            else
            {

                b[count]++;
            }
        }

        me(dp, -1);//初始化为-1,避免0对结果的影响
        k = min(count, k);//如果不穿拖鞋的天数大于妹子出现的天数,则让k等于妹子出现的天数
        dp[1][0][0] = 0, dp[1][1][1] = b[1];//给第一天穿拖鞋和第一天不穿拖鞋的情况赋值
        for(i = 1; i < count; i++)
        {
            for(j = 0; j <= k; j++)
            {
                if(dp[i][j][0] >= 0)//如果i天没穿鞋,则i+1天可以穿拖鞋
                {
                    dp[i+1][j+1][1] = dp[i][j][0] + b[i+1];
                    //dp[i+1][j+1][1] = max(dp[i][j][0] + b[i+1], dp[i+1][j+1][1]);
                    //明天不穿拖鞋的值等于 今天穿拖鞋的值加上明天遇见妹子数
                    dp[i+1][j][0] = dp[i][j][0];
                //dp[i+1][j][0] = max(dp[i][j][0] , dp[i+1][j][0]);
                //明天穿拖鞋的值等于今天穿拖鞋的值(因为不能连续两天穿拖鞋,所以今天穿了,明天就不能再穿)
                //存在dp[i][j][1]==-1的情况,所以下面的if语句执行不了,因此要在这里对dp[i+1][j][0]赋初值
                }
                if(dp[i][j][1] >= 0)//如果i天穿了鞋,则i+1天不可以穿拖鞋
                {
                    dp[i+1][j][0] = max(dp[i][j][1] , dp[i][j][0]);
                    //明天穿拖鞋的值等于 今天不穿拖鞋的值  与  今天穿拖鞋的值  的最大值
                }
            }
        }
        int ans = 0;
        for(i = 0; i <= 1; i++)
        {
            for(j = 0; j <= k; j++)
            {
                ans = max(ans, dp[count][j][i]);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值