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


    [SDOI2008]Sue的小球

    ( ext{Solution:})

    长得很像区间 (dp) 对吧,那猜的也差不多了。

    注意到有一个全局的总时间对答案造成影响,考虑把它给计算进 (dp) 值里面。

    也就是 (2009) 年论文说到的:

    费用提前计算

    其实是一个很简单的套路:把每一次转移消耗的时间造成的损耗加进 (dp) 值里面,这就可以省去 (dp) 状态中的时间这个维度了。

    所以自然设计出状态: (dp[l][r][0/1]) 表示完成区间 ([l,r]) 内所有球,且当前人在左边/右边的最大价值。

    转移直接看代码吧,比较显然。

    细节要注意:原来的错误原因是因为在 int 类型下把最大值设为了 (2^{31}-1) 导致运算的时候自然溢出导致错误,开 long long 就对了。

    错误特征:会输出一个和你设计的 (dp) 数组赋给的最值相反符号的数。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    typedef double db;
    const int MAXN=1.5e3+10;
    const db eps=1e-10;
    const int dyx=1LL<<50;
    namespace DyxAkIOI {
    	int n,pos,sum[MAXN];
    	struct point {
    		int x,y,v;
    		point(){x=0;y=0;v=0;}
    		bool operator<(const point&B)const{
    			return x<B.x;
    		}
    	} p[MAXN];
    	int sumv[MAXN];
    	int f[MAXN][MAXN][2];
    	inline int Max(int x,int y){return x>y?x:y;}
    	inline int Min(int x,int y){return x<y?x:y;}
    	inline int read() {
    		int s=0,w=1;
    		char ch=getchar();
    		while(!isdigit(ch)) {
    			if(ch=='-')w=-1;
    			ch=getchar();
    		}
    		while(isdigit(ch)) {
    			s=s*10-48+ch;
    			ch=getchar();
    		}
    		return s*w;
    	}
    	int getspeed(int l,int r){
    		return sumv[r]-sumv[l-1];
    	}
    	void Init() {
    		n=read();
    		pos=read();
    		for(int i=1;i<=n;++i)p[i].x=read();
    		for(int i=1;i<=n;++i)p[i].y=read();
    		for(int i=1;i<=n;++i)p[i].v=read();
    		p[++n].x=pos;
    		sort(p+1,p+n+1);
    		int P;
    		for(int i=1;i<=n;++i){
    			sumv[i]=sumv[i-1]+p[i].v;
    			if(p[i].x==pos)P=i;
    		}
    		for(int i=0;i<=n+1;++i)
    			for(int j=0;j<=n+1;++j)
    				f[i][j][0]=f[i][j][1]=-dyx;
    		f[P][P][0]=0;f[P][P][1]=0;
    		for(int len=2;len<=n;++len){
    			for(int l=1;l<=n-len+1;++l){
    				int r=l+len-1;
    				f[l][r][0]=p[l].y+Max(f[l+1][r][1]-(sumv[n]-getspeed(l+1,r))*(p[r].x-p[l].x),f[l+1][r][0]-(sumv[n]-getspeed(l+1,r))*(p[l+1].x-p[l].x));
    				f[l][r][1]=p[r].y+Max(f[l][r-1][0]-(sumv[n]-getspeed(l,r-1))*(p[r].x-p[l].x),f[l][r-1][1]-(sumv[n]-getspeed(l,r-1))*(p[r].x-p[r-1].x));
    			}
    		}
    //		cout<<Max(f[1][n][0],f[1][n][1])<<endl;
    //		for(int i=1;i<=n;++i)
    //			for(int j=1;j<=n;++j)
    //				printf("%d %d %c",f[i][j][0],f[i][j][1],j==n?'
    ':' ');
    		printf("%.3lf
    ",(double)(Max(f[1][n][0],f[1][n][1]))/1000.0);
    	}
    }
    
    signed main() {
    //	freopen("111.txt","r",stdin);
    	DyxAkIOI::Init();
    	return 0;
    }
    
  • 相关阅读:
    java实现第六届蓝桥杯立方尾不变
    java实现第六届蓝桥杯立方尾不变
    java实现第七届蓝桥杯寒假作业
    java实现第六届蓝桥杯隔行变色
    java实现第六届蓝桥杯隔行变色
    java实现第七届蓝桥杯交换瓶子
    使用JOTM实现分布式事务管理(多数据源)
    分布式系统事务一致性解决方案(转)
    SpringMVC,Mybatis,FreeMarker连接mycat示例(一)
    从零开发分布式数据库中间件 二、构建MyBatis的读写分离数据库中间件
  • 原文地址:https://www.cnblogs.com/h-lka/p/14995374.html
Copyright © 2020-2023  润新知