Codeforces Round #189 (Div. 1) Kalila and Dimna in the Logging Industry 斜率DP

来源:互联网 发布:古玩玉器交友软件 编辑:程序博客网 时间:2024/06/05 22:41

题目链接:http://codeforces.com/problemset/problem/319/C

以前不知道斜率DP优化,遇到这题,学会了,要加深印象:

题意大致是砍树,不一定按顺序看,目的是为了使充电费用最低,看完标号最大的树,充电就不再需要费用,所以关键在于求砍完标号最大的树所需要的最小花费,DP优化,记dp[i]为砍倒第i棵树所需要的最小花费,所以所以对于dp[n], dp[n] = min{ dp[j] + b[j] * a[n]}, j = 1, 2, 3, ...... n - 1。注意这里题目条件单调的,这可以作为斜率DP的一个标志。

分析如下:设现在要求dp[k], 在k之前的任意两个数,我们设为i, j, 且i < j < k; 那么dp[j] + b[j] * a[k] 和 dp[i] + b[i] * a[k]两个方案那个更优呢?作差比较, 移项化简得:如果 (dp[j] - dp[i]) / (bi - bj) < ak 则 方案 j 优于方案 i。(这里要注意吧bi递减,移项变号),我们把左边看作一个两点的斜率,得到一个函数G(j, i)如果G(j, i)< ak 则 j 优于 i。可以删除 i 方案。且以后 j 之后再有其他数,i 也不可能成为最优方案,因为 j 比 i 优。另外 当G(j, i) < G ( k , j )时, 可以删除 j 方案,因为这样 j 永远不会是最优方案, 以上两步优化维护了一个单调队列, 图形上看相邻两点的斜率单调递增或递减,所以叫斜率DP优化吧?原来复杂度n*n的降为了O(n),因为每个方案之进入队列一次,被提出以后不再加入。

代码如下:

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>#include<algorithm>#include<stack>#include<deque>#include<set>#include<vector>#include<iomanip>#include<cctype>#include<string>#include<memory>#include<map>#include<sstream>#include<cassert>#define mem(a) memset(a, 0, sizeof(a))typedef long long LL;typedef double dou;const int Mod = 1000000007;const double eps = 1e-8;const LL inf = 1e18;const int inf1 = 1e9;using namespace std;const int N = 100005;LL dp[N], qu[N], a[N], b[N];int main(){LL n, i, j, st, en, s = 1;cin >> n;for (i = 1; i <= n; ++i)cin >> a[i];for (i = 1; i <= n; ++i)cin >> b[i];st = 1;en = 2;qu[1] = 1;dp[1] = 0;for (i = 2; i <= n; ++i){while (st < en - 1 && (dp[qu[st + 1]] - dp[qu[st]]) < (b[qu[st]] - b[qu[st + 1]]) * a[i])st++;dp[i] = dp[qu[st]] + b[qu[st]] * a[i];while (st < en - 1 && en > 2 && (dou) (dp[qu[en - 1]] - dp[qu[en - 2]]) / (b[qu[en - 2]] - b[qu[en - 1]]) >= (dou) (dp[i] - dp[qu[en - 1]]) / (b[qu[en - 1]] - b[i]))en--;qu[en++] = i;}cout << dp[n] << endl;return 0;}

参考资料:

http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html

http://hi.baidu.com/prowindy/item/aa9ae4e285a6a4295b7cfb81?qq-pf-to=pcqq.c2c

推荐题目:http://acm.hdu.edu.cn/showproblem.php?pid=3507



原创粉丝点击