首页 > 其他分享 >CF38E Let's Go Rolling! 题解

CF38E Let's Go Rolling! 题解

时间:2024-03-07 13:44:53浏览次数:20  
标签:ch limits 题解 sum 小球 Rolling auto Go define

分析

考虑 DP。

因为 \(n \le 3000\),我们可以直接枚举插针的位置。定义状态函数 \(f_i\) 表示在从左往右第 \(i\) 个小球的位置上插针的最小花费。

枚举该小球右边第一个插针的位置,则 \(i\) 到 \(j-1\) 的小球都会滚到小球 \(i\) 的位置。代价为 \(\sum\limits_{k=i}^{j-1}x_k-x_i\)。所以有转移方程:\(f_i =\min\{f_j+\sum\limits_{k=i}^{j-1}x_k-x_i|i <j \le n+1\}+c_i\)。

这是个 \(O(n^3)\) 的 DP。但是不难发现 \(\sum\limits_{k=i}^{j-1}x_k-x_i\) 可以用前缀和优化掉。令 \(s_i=\sum\limits_{j=1}^{i}x_j-x_1\),则有 \(\sum\limits_{k=i}^{j-1}x_k-x_i=s_{j-1}-s_i-(j-1-i)\times(x_i-x_1)\)。

因为最左边小球的位置必定会插针,所以答案为 \(f_1\)。复杂度 \(O(n^2)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define pii pair<int,int>
#define x first
#define y second
#define gc getchar()
#define rd read()
#define debug() puts("------------")

namespace yzqwq{
	il int read(){
		int x=0,f=1;char ch=gc;
		while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc;}
		while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=gc;
		return x*f;
	}
	il int qmi(int a,int b,int p){
		int ans=1;
		while(b){
			if(b&1) ans=ans*a%p;
			a=a*a%p,b>>=1;
		}
		return ans;
	}
	il auto max(auto a,auto b){return (a>b?a:b);}
	il auto min(auto a,auto b){return (a<b?a:b);}
	il int gcd(int a,int b){
		if(!b) return a;
		return gcd(b,a%b);
	}
	il int lcm(int a,int b){
		return a/gcd(a,b)*b;
	}
	il void exgcd(int a,int b,int &x,int &y){
		if(!b) return x=1,y=0,void(0);
		exgcd(b,a%b,x,y);
		int t=x;
		x=y,y=t-a/b*x;
		return ;
	}
	mt19937 rnd(time(0));
}
using namespace yzqwq;

const int N=3005;
int n;
struct node{
	int x,c,s;
}a[N];
int f[N],s[N];

il bool cmp(node a,node b){
	return a.x<b.x;
}
il int getsum(int l,int r){
	return s[r]-s[l]-(r-l)*a[l].s;
}
il void solve(){
	n=rd;
	for(re int i=1;i<=n;++i) a[i]={rd,rd};
	sort(a+1,a+n+1,cmp);
	for(re int i=1;i<=n;++i) a[i].s=a[i].x-a[1].x,s[i]=a[i].s+s[i-1];
	memset(f,0x3f,sizeof(f));
	f[n+1]=0;
	for(re int i=n;i>=1;--i){
		for(re int lst=i+1;lst<=n+1;++lst){
			f[i]=min(f[i],f[lst]+getsum(i,lst-1)+a[i].c);
		}
	}
	printf("%lld\n",f[1]);
	return ;
}

signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int t=1;while(t--)
	solve();
	return 0;
}

标签:ch,limits,题解,sum,小球,Rolling,auto,Go,define
From: https://www.cnblogs.com/harmisyz/p/18058734

相关文章

  • P6390 [COCI2007-2008#4] POKLON 题解
    感谢@\(\color{#AEF}{\texttt{CelestialCyan}}\)大神对我的骚扰帮助。分析一眼DP。对于求最大满足条件区间数,我们定义状态函数\(\mathit{f}_{i}\)表示在第\(1\)到\(i\)个区间中选择,且必选第\(i\)个区间能够得到的最大长度。有转移方程:\(\mathit{f}_{i}=\max\{f[j]|......
  • UVA13095 Tobby and Query 题解
    分析一眼莫队(虽然通过这题的范围显然看出出题人用的不是莫队)。我们定义\(\mathit{cnt}_{i}\)表示数字\(i\)出现的次数。在指针的拓展增加\(x\)时,若有\(\mathit{cnt}_{x}+1=1\),则表示在在这个区间里,\(x\)是第一次出现的,我们可以将答案加\(1\);在指针的收缩减去\(x\)时,......
  • P5017题解
    前言做这道题,首先要了解\(dp\)。\(dp\)一般有三个步骤(个人理解):根据题意确定状态。根据状态的定义推出状态转移方程,一般有两种:填表法和刷表法。填表法就是普通\(dp\),用前面的状态转移到现在的状态,例:\(f[i]=f[i-1]+a[i]\)。刷表法就是在现有的基础上(\(f[i]\)已知),去推出\(f[......
  • SP20848 IGAME - Interesting Game 题解
    分析数位DP一眼题。对于一个\(k\)位的数\(s\),我们不妨将其看做由数字\(s_1,s_2,s_3,\dots,s_k\)这\(k\)个数字拼接起来的。而题意是每个人可以将\(s_1,s_2,s_3,\dots,s_k\)中的任意一个减去任意数字,保证不减去\(0\)且结果\(\ge0\)。显然,在我们将这\(k\)个数看......
  • AT_abc216_g [ABC216G] 01Sequence 题解
    分析一道差分约束题。我们令\(\mathit{sum}_{i}\)表示\(1\)到\(i\)中,\(1\)的数量,根据题意可得:\(\mathit{sum}_{l_i-1}+x_i\le\mathit{sum}_{r_i}\)\(\mathit{sum}_{l+1}+(-1)\le\mathit{sum}_{l}\)\(\mathit{sum}_{l}+0\le\mathit{sum}_{l+1}\)因为我们要尽......
  • CF1066E 题解
    Solution首先不难想到计算\(a\)的每一位对答案产生的贡献,然后题目告诉我们\(b\)每次会往右移一位,然后结合样例可以发现:对于\(a\)的第\(i\)位,能与其产生贡献的条件是:\(a_i=1\)且\(b_j=1(i\leqj)\),对答案的贡献不难想出即为\(2^{i-1}\times\sum\limits_{j=i}^{m}b_j......
  • AT_abl_e Replace Digits 题解
    分析线段树模板题。维护一个区间\([l,r]\)中\(\sum\limits_{i=l}^r10^{n-i}\)的答案。将某个区间\([l,r]\)全部修改成\(x\)之后的表示的数就是\(x\times(\sum\limits_{i=l}^r10^{n-i})\)。区间修改可以用线段树,用快速幂或者预处理弄出来\(10^x\),建树的时候就能把每......
  • AT_abl_d Flat Subsequence 题解
    分析线段树模板题。一眼DP。定义状态函数\(\mathit{f}_i\)表示前\(i\)个数中,必选\(\mathit{A}_i\)时\(B\)的最大长度。则有转移方程:\(\mathit{f}_i=\max\{f_j|((1\lej\lei-1)\land(-k\leA_i-A_j\lek))\}+1\)。答案就是\(\max\limits_{i=1}^{n}\mathit{f}_i......
  • CF808E 题解
    很好的一道分类讨论题。观察数据范围,\(w\leq3\),不难想到,将\(w\)分为\(1,2,3\)种情况,如果直接贪心选会不难发现是错的。但是如果\(w\)的值只有\(2\)种,就像\(w=1/2\)的情况,将\(w=1/2\)的数据按价值排序,最后枚举每种选多少即可。但是\(w=3\)就会显得难以处理,需要讨......
  • CF1824B1 LuoTianyi and the Floating Islands (Easy Version) 题解
    分析按照\(k\)的奇偶分开考虑。\(k\)为奇数。一个好的节点有且仅有一个在任意两个有人的节点\(i,j\)的路径的交点上的最优位置。若该交点偏移\(1\)步,则必然会使路径长度和\(+1\)。故期望为\(1\)。\(k\)为偶数。任意一个好的节点仍然在任意两个有人的节点\(i,j\)的......