zoukankan      html  css  js  c++  java
  • 题解 P4870 【[BalticOI 2009 Day1]甲虫】

    题意

    甲虫在坐标轴0位置,左右移动使得喝到的水最多,同时一单位时间甲虫可以移动一个单位距离,一单位时间每滴水分蒸发1单位体积

    思路

    考场上没有看懂题目,把水滴的体积和单位距离搞混了
    这道题是一道很好的(dp)题目,其关键在于怎么定义
    按照一般的定义,(dp_{[l][r][0/1]})表示已经喝了(l)(r)区间的水之后,在(l)(r)位置,喝到的水的最大值,但是对于不同的值而言,经过的时间不一样,无法算出下一次转移时新水滴的贡献,换句话说,就是不同的值对应的经过的时间不同,值最大的不一定是最优的,如果维护了时间和喝的总水滴体积,把每种状态全部存下来,并不好处理,时间复杂度很差,考虑换种定义状态
    在枚举一个(len)(表示要喝(len)滴水)的前提下,定义(dp_{[l][r][0/1]})表示已经喝了(l)(r)区间内所有的水滴,所浪费的水体积最小值,所谓浪费的水体积也就是蒸发掉的水体积数,其中包括了还没有喝的((len - (r - l + 1)))滴水和已经喝掉的((r - l + 1))滴水的总浪费。
    此时浪费的水滴数很好算,知道了还没有喝的水滴数和这次需要移动的长度(即话费的时间),这次转移多浪费的水滴体积就是((len - (r - l + 1) - 1)) ( imes) $igtriangleup x $
    转移方程
    定义(len)表示这次要喝(len)滴水,(siz = (r - l + 1))
    (dp_{[i][j][0]}) = (min(dp_{[l + 1][r][0]} + (len - siz + 1) * (x[l + 1] - x[l]), dp_{[l + 1][r][1]} + (len - siz + 1) * (x[r] - x[l])))
    (dp_{[i][j][1]}) = (min(dp_{[l][r - 1][1]} + (len - siz + 1) * (x[r] - x[r - 1]), dp_{[l][r - 1][0]} + (len - siz + 1) * (x[r] - x[l])))

    (Code)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    const int maxn = 405;
    int n, m;
    long long dp[maxn][maxn][2];
    long long ans;
    int x[maxn];
    int main () {
    	freopen ("beetle.in", "r", stdin);
    	freopen ("beetle.out", "w", stdout);
    	n = read(), m = read();
    	int flag = 0;
    	for (register int i = 1; i <= n; i++) {
    		x[i] = read();
    	}
    	x[++n] = 0;
    	sort (x + 1, x + 1 + n);
    	int pos = lower_bound(x + 1, x + 1 + n, 0) - x;
    	int r;
    	for (register int len = 1; len <= n; len++) {
    		memset (dp, 0x7f, sizeof dp);
    		dp[pos][pos][0] = 0, dp[pos][pos][1] = 0;
    		for (register int siz = 2; siz <= len; siz++) {
    			for (register int l = 1; l + siz - 1 <= n; l++) {
    				r = l + siz - 1;
    				dp[l][r][0] = min (dp[l + 1][r][0] + (len - siz + 1) * (x[l + 1] - x[l]), dp[l][r][0]);
    				dp[l][r][0] = min (dp[l + 1][r][1] + (len - siz + 1) * (x[r] - x[l]), dp[l][r][0]);
    				dp[l][r][1] = min (dp[l][r - 1][1] + (len - siz + 1) * (x[r] - x[r - 1]), dp[l][r][1]);
    				dp[l][r][1] = min (dp[l][r - 1][0] + (len - siz + 1) * (x[r] - x[l]), dp[l][r][1]);
    				ans = max (ans, m * (siz - 1) - dp[l][r][1]);
    				ans = max (ans, m * (siz - 1) - dp[l][r][0]);
    			}
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    SQL的四种连接(内连接,外连接)
    MySQL连表操作之一对多
    [转]Mysql连表之多对多
    Hibernate笔记二
    Hibernate框架报错:org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.mikey.hibernate.domain.Person.pid
    Hibernate框架:org.hibernate.exception.SQLGrammarException: Cannot open connection at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java92)
    [转]网络编程三要素
    Hibernate笔记一
    JavaScript高级特征之面向对象笔记
    Myeclipse创建HTML文件中文显示乱码问题
  • 原文地址:https://www.cnblogs.com/hzoi-liujiahui/p/14061639.html
Copyright © 2011-2022 走看看