ZOJ 3469 Food Delivery(区间DP,经典题)
2015-10-29 18:59
351 查看
题目大意:
有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了以后有更多的家庭订购,要将外卖送到的情况下使得所有用户的不开心值总和达到最小
很明显,每多走一分钟,没送到的家庭的不开心值都会加倍。
dp[i][j][0]记录从i到j区间最小的不开心值,且走完(i,j)之后停留在i,dp[i][j][1]表示停留在j。
状态转移方程:dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][0] + (sum + a[i].b) * (a[i+1].x - a[i].x), dp[i+1][j][1] + (sum + a[i].b) * (a[j].x - a[i].x))。
dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][1] + (sum + a[j].b) * (a[j].x - a[j-1].x), dp[i][j-1][0] + (sum + a[j].b) * (a[j].x - a[i].x))。
sum表示的是(i,j)外还未到达的不开心值和。
有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了以后有更多的家庭订购,要将外卖送到的情况下使得所有用户的不开心值总和达到最小
很明显,每多走一分钟,没送到的家庭的不开心值都会加倍。
dp[i][j][0]记录从i到j区间最小的不开心值,且走完(i,j)之后停留在i,dp[i][j][1]表示停留在j。
状态转移方程:dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][0] + (sum + a[i].b) * (a[i+1].x - a[i].x), dp[i+1][j][1] + (sum + a[i].b) * (a[j].x - a[i].x))。
dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][1] + (sum + a[j].b) * (a[j].x - a[j-1].x), dp[i][j-1][0] + (sum + a[j].b) * (a[j].x - a[i].x))。
sum表示的是(i,j)外还未到达的不开心值和。
#include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdio> #include <vector> #include <string> #include <queue> #include <stack> #include <cmath> #include <set> #include <map> using namespace std; typedef long long LL; #define mem(a, n) memset(a, n, sizeof(a)) #define ALL(v) v.begin(), v.end() #define si(a) scanf("%d", &a) #define sii(a, b) scanf("%d%d", &a, &b) #define siii(a, b, c) scanf("%d%d%d", &a, &b, &c) #define pb push_back #define eps 1e-8 const int inf = 0x3f3f3f3f, N = 1e3 + 5, MOD = 1e9 + 7; int T, cas = 0; int n, m; int x0, v, st, sum ; int dp [2]; struct node { int x, b; }a ; bool cmp(node a, node b) { return a.x < b.x; } int min(int a, int b, int c) { return min(a, min(b, c)); } int main(){ #ifdef LOCAL freopen("/Users/apple/input.txt", "r", stdin); // freopen("/Users/apple/out.txt", "w", stdout); #endif while(siii(n, v, x0) != EOF) { mem(sum, 0); mem(dp, 0x3f); for(int i = 1; i <= n; i ++) sii(a[i].x, a[i].b); n ++; a .x = x0, a .b = 0; sort(a + 1, a + n + 1, cmp); for(int i = 1; i <= n; i ++) { sum[i] = sum[i-1] + a[i].b; if(a[i].x == x0) st = i; } dp[st][st][0] = dp[st][st][1] = 0; for(int i = st; i >= 1; i --) { for(int j = st; j <= n; j ++) { int tmp = sum[i-1] + sum - sum[j]; if(i == j) continue; dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][0] + (tmp + a[i].b) * (a[i+1].x - a[i].x), dp[i+1][j][1] + (tmp + a[i].b) * (a[j].x - a[i].x)); dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][1] + (tmp + a[j].b) * (a[j].x - a[j-1].x), dp[i][j-1][0] + (tmp + a[j].b) * (a[j].x - a[i].x)); } } printf("%d\n", min(dp[1] [0], dp[1] [1]) * v); } return 0; }
相关文章推荐
- OC语法 --- KVC
- GDB远程连接RX Probe在线debug程序
- 转 运维技能图谱
- javax.servlet.jsp.JspException: No collection found
- Android 动画之ScaleAnimation应用详解
- 10个免费的响应式jQuery Carousel 轮播图插件
- 认识与入门 Markdown,Markdown教程
- 第九周--项目2对称矩阵压缩存储的实现与应用(1)
- C++primer学习:面象对象程序设计(5):容器与继承
- 数据结构之并查集
- javascript 时间处理问题
- appium for windows 环境搭建
- 第九周--项目1猴子选大王 (数组版)
- Dinic 算法求最大流(最小割) POJ 2536
- 关于UIInterfaceOritation 和 UIDeviceOritation
- export http://blog.csdn.net/hikaliv/article/details/4474835
- 机器学习2_逻辑回归和标准化的逻辑回归_AndrewNG
- 高通平台msm8909 LK 实现LCD 兼容
- Leetcode -- Best Time to Buy and Sell Stock IV
- 为Web程序员准备的10个最棒的jQuery视频插件