Codeforces 727 F. Polycarp's problems

Description

有一个长度为 \(n\) 有正负权值的序列,你一开始有一个值,每次到一个权值就加上,最少需要删掉多少数值才能到序列末尾.\(n \leqslant 750,m \leqslant 2 \times 10^5\)

Sol

DP+二分.

发现这个东西有后效性,就是前面选不选会影响后面的决策,并且权值太大无法记录.

但是我们可以倒着做,因为后面的决策无法影响前面的决策.

\(f[i][j]\) 表示到 \(i\) 删掉 \(j\) 个至少需要的初始权值.

因为初始权值非负,所以不可能在中途中出现负数,要处理掉,然后就两个决策,删或不删,转移就很好写了.

统计答案的时候他有单调性,可以二分.

Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

typedef long long LL;
const int N = 755;

int n,m;
LL a[N],f[N][N],w[N];

inline LL in(LL x=0,char ch=getchar()){ while(ch>‘9‘||ch<‘0‘) ch=getchar();
	while(ch>=‘0‘ && ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar();return x; }
void work(LL x){
	int l=0,r=n,mid;
	while(l<=r){
		mid=(l+r)>>1;
		if(f[1][mid] <= x) r=mid-1;
		else l=mid+1;
	}printf("%d\n",l);
}
int main(){

	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) cin>>a[i];

	memset(f,0x3f,sizeof(f));
	f[n+1][0]=0LL;
	for(int i=n;i;i--) for(int j=0;j<n-i+1;j++){
		f[i][j]=min(f[i][j],max(0LL,f[i+1][j]-a[i]));
		f[i][j+1]=min(f[i][j+1],f[i+1][j]);
	}

	for(;m--;) work(in());
	return 0;
}

  

Codeforces 727 F. Polycarp's problems

时间: 2024-11-10 01:10:42

Codeforces 727 F. Polycarp's problems的相关文章

codeforces727F Polycarp&#39;s problems(dp)

题意: 给你一个长度为n(750)的数列,数的范围是(1e9-1e9),必须按顺序从左端走到右端, 每到一个位置,当前的值就加上当前位置的值,给你m(2e5)个询问,每个询问给你一个初始值, 问你至少要去掉几个位置的值才能保证行进过程中不会出现负数 思路: http://blog.csdn.net/aufeas/article/details/53031439 大神的dp思路 令f[i][j]表示从第i~n个问题中留下 j 个问题所需要的最小心情值,这样我们只需要知道过程中的心情值即可, 因为最

【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

[题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模924844033.n<=2*10^5. [算法]排列组合+NTT [题解]考虑每个点只会在k个点都在其一个子树时无贡献,即: $$ANS_k=\sum_{x=1}^{n}\binom{n}{k}-\sum_{y}\binom{sz[y]}{k}+\binom{n-sz[y]}{k}$$ 令$cnt_i$表示满足s

Codeforces 835 F. Roads in the Kingdom

\(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗树,并最小化删掉环边后的树的直径. \(n \leq 2 \times 10^5\) 树的边权 $ \leq 10^9 $ 解题思路 : 考虑最终树的直径可能由两部分组成,答案是其中的最大值 第一种就是外向树内的直径的最大值,这个只需要随便\(dp\)一下即可,这里不过多讨论 第二种情况树的直径经过原来的环,

Codeforces 1166 F. Vicky&#39;s Delivery Service 并查集+set

题意:有n个点,m条边,边有c种颜色,q次操作. 每个边都有一种颜色. 然后操作有两种,一种是再加一条边,另一种是查询能否从x达到y. 移动的限制是,连着走两步必须是同一种颜色,如果走奇数步,最后一步可以是任意颜色. 例子:1-2-3-4-5-6. 这个题颜色种类很多,我是用map<int,vector<int>>来存边. 我们首先可以想到 对于点x同种颜色连着的点都是可以相互移动的,所以我们可以用这种方法将它们用并查集合并,所以我们也可以直接map<int,int>来

# codeforces 1272 F. Two Bracket Sequences(三维dp + bfs)

codeforces 1272 F. Two Bracket Sequences(三维dp + bfs) 题目大意 输入两个括号序列 s,t(不一定合法),你需要构造一个尽可能短的合法括号序列使得s,t 都是这个序列的子序列(子序列意味着不用连续) 解题思路 dp[i][j][k]表示匹配到s的第i个字符,匹配到t的第j个字符,并且此时(的个数比)多k个的时候的最小合法序列长度,k的上限是200(s和t中最多200个(或者)). 状态转移: 枚举答案合法序列的每一位是放置(或者) ? 放置(,如

Codeforces 589F F. Gourmet and Banquet(二分+贪心)

题目地址:http://codeforces.com/problemset/problem/589/F 思路:先贪心按照右端点值排序(先把对后面影响最小的菜吃掉),二分吃每道菜的时间即可. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=105; const int maxt=1e5+50

codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: dp[i]表示前i个字符需要的最小次数. dp[i] = min(dp[j]+w(j+1,i)); (0<=j<i); [j+1,i]如果存在循环节(自身不算),那么取最小的循环节x.w = digit((i-j)/x)+x; 否则w = i-j+1; 求一个区间最小循环节: 证明:http://w

codeforces 985 F. Isomorphic Strings

题目链接 https://codeforces.com/contest/985/problem/F 题意 首先定义两个长度相等字符串a,b同构,当且仅当a中的每个字母,b中只存在一个字母与之对应,并且两个字母出现位置要完全一致,a,b反过来也要满足. 给定一个长度为\(2 \times 10^5\)的字符串s,有很多次询问.每次询问s从x位置开始的长度为l的字串与从y开始的长度为l的字串是否同构. 分析 对每个字母出现位置的集合进行哈希. 比如对于字母\('k'\),我们把原串中出现\('k'\

【Codeforces 723C】Polycarp at the Radio 贪心

n个数,用最少的次数来改变数字,使得1到m出现的次数的最小值最大.输出最小值和改变次数以及改变后的数组. 最小值最大一定是n/m,然后把可以改变的位置上的数变为需要的数. http://codeforces.com/problemset/problem/723/C Examples input 4 21 2 3 2 output 2 11 2 1 2 input 7 31 3 2 2 2 2 1 output 2 11 3 3 2 2 2 1 input 4 41000000000 100 7