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?