动态规划训练25 [Food Delivery ZOJ
来源:互联网 发布:windows怎么开ssh 编辑:程序博客网 时间:2024/06/05 20:47
Food Delivery
ZOJ - 3469区间DP的一道好题。
在这道题里,无非就是从出发点向左走到x1再向右走到有y1,再向左走到x2,再向右走到y2.。。。这样,一直将所有的顾客遍历完。
显然,起点这个点是非常特殊的一个点,我们姑且也把它算作一名顾客,那么这名顾客的愤怒值设置为0。
然后定义dp[x][y][0]表示区间遍历完[x,y]了,并且当前停留在x位置上,将对最终的愤怒值之和造成的贡献。
定义dp[x][y][1]表示遍历完区间[x,y],并且当前停留在y位置上,将对最终的愤怒之和造成的贡献。
从上面我们的讨论中可以发现[x,y]一定是包含起始点S的,不然这个区间将没有意义。
我们可以得到状态转移的方程 (我们没有在这里就把V乘进去,而是在最后才把V考虑进去)
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (Ns[i+1].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (Ns[j].x - Ns[j-1].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));
以上的状态转移方程就相当于把区间扩大了一位数字,贡献增加的值。
我看很多题解的时候,没有明确说明dp表示的是对于答案的贡献值,所以没能充分的理解。
反思这个动态规划的题目,有点特别,就是说dp代表的东西不能形成一个类似的独立的子问题,而仍然是刻画原问题的某个性质的一部分,这里我觉得是与其他一些dp不同的地方。
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;int N,V,X; const int INF = 1e9;const int MAX = 1005;struct node{int x,val;friend bool operator<(node n1,node n2){return n1.x < n2.x;}}Ns[MAX];int dp[MAX][MAX][2];int sum[MAX];int main(){while(~scanf("%d%d%d",&N,&V,&X)){memset(dp,0,sizeof(dp));for(int i = 1;i <= N;i++){int x,b;scanf("%d%d",&x,&b);Ns[i].x = x;Ns[i].val = b;}Ns[N+1].x = X;Ns[N+1].val = 0;sort(Ns+1,Ns+N+2);int s = 0;while(Ns[++s].x != X);for(int i = 1;i <= N+1;i++) sum[i] = sum[i-1] + Ns[i].val;for(int i = 1;i <= N+1;i++){for(int j = 1;j <= N+1;j++){dp[i][j][0] = dp[i][j][1] = INF;}}dp[s][s][0] = dp[s][s][1] = 0;for(int i = s;i > 0;i--){for(int j = s;j<= N+1;j++){if(i == j) continue;dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (Ns[i+1].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j] - sum[i])));dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (Ns[j].x - Ns[j-1].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (Ns[j].x - Ns[i].x)*(sum[N+1] - (sum[j-1] - sum[i-1])));}}int ans = min(dp[1][N+1][0],dp[1][N+1][1]);printf("%d\n",ans*V);}return 0;}
- 动态规划训练25 [Food Delivery ZOJ
- Food Delivery zoj 3469
- ZOJ 3469 Food Delivery
- ZOJ 3469 Food Delivery
- ZOJ 3469 Food Delivery
- ZOJ-3469 Food Delivery
- ZOJ 3469 Food Delivery
- Food Delivery ZOJ
- ZOJ 3469 Food Delivery(DP)
- Food Delivery - ZOJ 3469 dp
- Zoj 3469 Food Delivery (DP
- ZOJ 3469 Food Delivery DP
- ZOJ 1196 Fast Food 动态规划
- ZOJ 3469 Food Delivery / 区间DP
- ZOJ 3469 Food Delivery (区间dp)
- zoj 3469 Food Delivery(区间dp)
- zoj 3469 Food Delivery(区间dp)
- ZOJ 3469 - Food Delivery(区间DP)
- 简单说 eval( )函数
- AngularJS2+Eclipse环境搭建
- ios常用的格式化代码工具
- Linux远程登录命令:Telnet
- Python: logging日志模块详解
- 动态规划训练25 [Food Delivery ZOJ
- kotlin学习--基本语法
- JDBC和Hibernate的区别
- 线程本地存储(TLS)的学习
- 哪些码农小习惯预示着高薪资?
- 文件上传下载UploadUtil
- 00201 数据库基础:函数、触发器TRIGGER和存储过程PROCEDURE
- RxJava处理嵌套请求
- ubuntu pthread 相关manpage