首页 > 其他分享 >题解【P2466 [SDOI2008] Sue 的小球】

题解【P2466 [SDOI2008] Sue 的小球】

时间:2022-09-06 09:11:56浏览次数:113  
标签:ch int 题解 include P2466 right inline SDOI2008 define

题目传送门

一眼丁真,鉴定为 原题

现将所有点按照 \(x\) 排序,区间 \([l,r]\) 的终点一定是 \(l\) 或 \(r\),否则会跑冤枉路。

设 \(f_{i,j,0/1}\) 表示在区间 \([i,j]\) 最终落在 左端点 / 右端点 的最大价值。

但这样是寄的,这个 DP 有后效性,当前花费的时间会对之后产生影响,小球的贡献跟时间有关。

考虑区间 \([i,j]\) 中 \(i\) 的贡献 \(\left(y_i-v_it\right)\),\(t\) 表示之前决策的时间总和,是不是说明我们可以把 \(v_it\) 这个量在 DP 过程中进行计算?

具体的,我们每一动一次,都会把未来减少的得分 \(v_it\) 计算在内,比如对于一个状态 \((i-1,j,0)\),转移到 \((i,j,0)\),我们不光要计算 \(i\) 的贡献,还要将其它所有正在下落的小球的贡献计算上。

我们可以用一个前缀和 \(s_i\) 表示某一个区间下落速度之和,即令 \(s_{i,j}\leftarrow V-\sum \limits_{k=i}^j v_k\)。其中 \(V\) 表示所有小球的下落速度之和。

那么我们可以得到状态转移方程:

\[\begin{cases} f_{i,j,0}\leftarrow y_i+\max\{f_{i+1,j,0}-s_{i+1,j}\left(x_{i+1}-x_{i}\right),f_{i+1,j,1}-s_{i+1,j}\left(x_{j}-x_i\right)\} \\ f_{i,j,1}\leftarrow y_j+\max\{f_{i,j-1,0}-s_{i,j-1}\left(x_j-x_i\right),f_{i,j-1,1}-s_{i,j-1}\left(x_j-x_{j-1}\right)\} \end{cases} \]

初始值:\(f_{i,i,0/1}\leftarrow y_i+V |x0-x_i|\)。

时间复杂度 \(\Theta(n^2)\),可以通过本题。

代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define rep(i,a,b) for(register int i=a;i<=b;++i)
#define rev(i,a,b) for(register int i=a;i>=b;--i)
#define gra(i,u) for(register int i=head[u];i;i=edge[i].nxt)
#define Clear(a) memset(a,0,sizeof(a))
#define yes puts("YES")
#define no puts("NO")
using namespace std;
typedef long long ll;
const int INF(1e9+10);
const ll LLINF(1e18+10);
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=s*10+(ch-'0'),ch=getchar();
	return s*w;
}
template<typename T>
inline T Min(T x,T y){return x<y?x:y;}
template<typename T>
inline T Max(T x,T y){return x>y?x:y;}
template<typename T>
inline void Swap(T&x,T&y){T t=x;x=y;y=t;return;}
template<typename T>
inline T Abs(T x){return x<0?-x:x;}

const int MAXN(1010);

int n,x0;
struct node{int x,y,v;};
node a[MAXN];

ll f[MAXN][MAXN][2],V,sum[MAXN];

inline bool cmp(node x,node y){return x.x<y.x;}

inline ll s(int x,int y){return V-(sum[y]-sum[x-1]);}

int main()
{
//	freopen("read.txt","r",stdin);
	memset(f,~0x7f,sizeof(f));
	n=read(),x0=read();
	rep(i,1,n) a[i].x=read();
	rep(i,1,n) a[i].y=read();
	rep(i,1,n) a[i].v=read(),V+=a[i].v;
	a[++n].x=x0;
	sort(a+1,a+1+n,cmp);
	rep(i,1,n) sum[i]=sum[i-1]+a[i].v;
	rep(i,1,n) f[i][i][0]=f[i][i][1]=a[i].y-1ll*Abs(x0-a[i].x)*V;
	rep(d,2,n) rep(i,1,n-d+1)
	{
		int j=i+d-1;
		f[i][j][0]=a[i].y+Max(f[i+1][j][0]-1ll*s(i+1,j)*(a[i+1].x-a[i].x),f[i+1][j][1]-s(i+1,j)*1ll*(a[j].x-a[i].x));
		f[i][j][1]=a[j].y+Max(f[i][j-1][0]-1ll*s(i,j-1)*(a[j].x-a[i].x),f[i][j-1][1]-s(i,j-1)*1ll*(a[j].x-a[j-1].x));
	}
	printf("%.3lf\n",Max(f[1][n][0],f[1][n][1])/1000.0);
	return 0;
}
/*
Date : 2022/9/6
Author : UperFicial
Start coding at : 8:30
finish debugging at : 9:00
*/

标签:ch,int,题解,include,P2466,right,inline,SDOI2008,define
From: https://www.cnblogs.com/UperFicial/p/16660554.html

相关文章

  • 1217F 不是题解
    图,动态,连通性,假装强制在线但并不是。 线段树分治是什么?沿着时间建线段树,把logn个操作插到线段树里面,然后就可以简单的增/删了这一题,把可能的两条边都插入线段树。到......
  • 【题解】做题记录(2022.9)
    可能会断断续续的,是因为可能有的时候忘记了写记录9.5今天搞了一天的平衡树,但大部分都是比较基础的操作[SHOI2009]会场预约题目分析:set大法吼啊我们考虑重新定义两个......
  • noi.ac#15 题解
    做了一下午还多,完全独立完成。题意很简单:给树加一条边使得最大匹配数增加1。什么样的边\((a,b)\)满足条件呢?很明显,当且仅当存在一个最大匹配不选\(a,b\)。此时加上\(......
  • 【题解】[SDOI2009] 虔诚的墓主人
    题意传送门\(N\timesM\)的矩形,格点是共\(W\)棵常青树或墓地。对于一块墓地,它的虔诚度为让它正上下左右各恰有\(k\)棵常青树的方法数量。求出整个矩形公墓的虔诚度总......
  • 题解【CF1025D Recovering BST】
    题目传送门肉眼观察题。设\(f_{i,j,k}\)表示区间\([i,j]\)的根为\(k\)时能否还原。这样枚举一个根\(k\),分别枚举两个儿子在两个区间的位置转移就好了,由于两个儿子......
  • ARC147题解(A~E)
    \(A\)\(Problem\)给定长度为\(n\)的序列\(A\),要求重复执行以下操作,直到\(A\)中的元素个数为\(1\):选出下标\(i\),使得\(A_i\)是\(A\)中剩余的数中最大的;选出......
  • leetcode 6356 最长回文子串长度,最长回文子串 C/C++ 动态规划方案 同样的用例,测试执
    对dp变量需要执行初始化,否者LeetCode会出现同样的用例,单独执行可以通过,提交代码执行不通过的情况。 下面是找最长回文串的动态规划代码。class Solution {public:......
  • 题解【CF1316E Team Building】
    题目传送门状压DP入门题。设\(f_{i,S}\)表示考虑了前\(i\)个人,队伍放置情况为\(S\)时(0表示放置了队员,1表示没有放置)的最大贡献。然后分讨一下\(i\)是去当队......
  • 【题解】CF1585E Frequency Queries
    思路by@houzhiyuanSol感觉在线不怎么可做,考虑离线。那么问题变成了维护路径上第\(k\)大出现次数的数。考虑线段树,以出现次数为节点的下标,那么查询相当于是求第\(k......
  • 攻防世界 new_easypwn 题解
    攻防世界new_easypwn题解程序分析查看程序基本情况,如图,该程序是64位程序,开启了Canary、NX、PIE保护。使用ida64打开分析程序,该程序是个电话录之类的,可以添加、删除、......