https://codeforces.com/contest/1400/problem/E
据说是群友前几天才做到的腾讯笔试原题?还是抄的以前cf的原题?
https://codeforces.com/problemset/problem/448/C
sb题目又想了一年,某bhu牛逼网友14分钟过了,基础dp功力还是不够。。。
设f[i]为i是用2操作单选过来的,前i个拿完的最优值,g[i]为i是用1操作从之前某个地方延续过来的,前i个拿完的最优值
f[i]=min(f[i-1],g[-1])+(a[i]>0);
而g[i]如果要从前面某个g[j]的位置一路延续到 i 这个位置,需要满足min{a[j]....a[i-1]}==min(a[i],a[j]),因为a[j]是被延续过来且消完的,他想继续从j用1操作延续到a[i]就要保证中中间的值都大于等于min(a[i],a[j])。
那么我们用一个st表O(1)维护区间最小值,就可以判断是否可以转移过来了,然后从g[j]转移到g[i]的话,那么j+1到i-1肯定全部用2操作就好了,因为如果你j+1到i-1中间有延续的话,反正也可以延续到i,所以这么转移取min值肯定能得到g[i]的最小值
其实也可以不用st表,直接从后往前边跑边记录最小值就知道能不能转移了
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxl=5010;
int n,m,cas,k,cnt,tot,ans,up;
int a[maxl],b[maxl];
ll st[15][m