D. Jellyfish and Mex

题目:

链接:https://codeforces.com/problemset/problem/1875/D
思路:
这题刚开始没啥想法,后面推演了一下发现是个动态规划:

从左到右先找出首先为0的点,那么我要求的值就是这个区间内的值。然后假设先把ax清为0,那么所加的值就是ax*ptr,对比发现就是上一阶段的小规模。所以可以用递推公式:
minn[i] = min(minn[i],minn[j] + a[j]*i)指的是以i为ptr(末节点),优先清除j位的数字。
这里数据注意:a∈[0,1e9]但是最多只有5e3的数据,所以大于5e3的直接丢掉就好。
代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
typedef long long ll;
const int N = 5010;
ll a[N];
ll minn[N];
int main()
{
	IOS;
	int t; cin >> t;
	while (t--)
	{
		ll n; cin >> n;
		memset(a, 0, sizeof(a));
		for (int i = 1; i <= n; i++) { int x; cin >> x;if(x<=5000) a[x]++; }
		ll rtx = 0;
		while (rtx <= n and a[rtx])rtx++;
		minn[0] = 0;
		for (int i = 1; i <= rtx; i++)
		{
			for (int j = 0; j < i; j++)
			{
				if (j == 0)
					minn[i] = minn[j] + a[j] * i;
				else
					minn[i] = min(minn[i], minn[j] + a[j] * i);
			}

		}
		cout << minn[rtx] - rtx << '\n';
		
	}
	return 0;
}

颗秒,感觉评分没有1600?

posted on 2024-07-03 19:42  WHUStar  阅读(3)  评论(0编辑  收藏  举报