题目描述
找对象可不是一件容易的事情,如果你想找个好对象啊,喜欢打游戏的得把游戏戒了,喜欢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;
}