费用提前计算相关的DP(BZOJ2037,POJ3042,ZOJ3469)
在刷ZeroClock大神的区间DP专辑,遇见了ZOJ3469,完全不无从下手,然后有人说是论问题,推荐看徐源盛《对一类动态规划问题的研究》这篇论文,果断得膜拜了下,感觉好神奇,可以把未来的费用提前计算好~~~顺便把相关的三道题A了,其实都是一样的。。。
BZOJ2037 [Sdoi2008]Sue的小球
题目大意
中文的。。。
题解
这是论文的例题
直接上原文的讲解吧。。。

把dp数组初始化为0x7fffffffWA了,改成0x3f3f3f3f就AC了。。。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>
using namespace std;
#define MAXN 1005
#define INF 0x3f3f3f3f
int dp[2][MAXN][MAXN];
int sum[MAXN];
bool visit[MAXN][MAXN];
int n,x0;
typedef struct
{
int x,y,v;
} NODE;
NODE a[MAXN];
bool cmp(const NODE a,const NODE b)
{
return a.x<b.x;
}
void dfs(int l,int r)
{
if(visit[l][r]) return;
if(l==r)
{
if(a[r].x==x0)
dp[0][l][r]=dp[1][l][r]=0;
else dp[0][l][r]=dp[1][l][r]=-INF;
return;
}
visit[l][r]=1;
dfs(l+1,r);
dfs(l,r-1);
dp[0][l][r]=a[l].y+max(dp[0][l+1][r]-(a[l+1].x-a[l].x)*(sum[n]-sum[r]+sum[l]),
dp[1][l+1][r]-(a[r].x-a[l].x)*(sum[n]-sum[r]+sum[l]));
dp[1][l][r]=a[r].y+max(dp[1][l][r-1]-(a[r].x-a[r-1].x)*(sum[n]-sum[r-1]+sum[l-1]),
dp[0][l][r-1]-(a[r].x-a[l].x)*(sum[n]-sum[r-1]+sum[l-1]));
return;
}
int main()
{
scanf("%d%d",&n,&x0);
for(int i=1; i<=n; i++)
scanf("%d",&a[i].x);
for(int i=1; i<=n; i++)
scanf("%d",&a[i].y);
for(int i=1; i<=n; i++)
scanf("%d",&a[i].v);
a[++n].x=x0;
sort(a+1,a+n+1,cmp);
sum[0]=0;
for(int i=1; i<=n; i++)
sum[i]=sum[i-1]+a[i].v;
dfs(1,n);
printf("%.3lf\n",(double)(max(dp[0][1][n],dp[1][1][n]))/1000.0);
return 0;
}
POJ3042 Grazing on the Run
题目大意
在X坐标轴上有n堆草,有一条牛的初始位置是在坐标L,牛(移动速度为1个单位/s)每次可以向左或者向右把一堆草吃掉,每堆草有一个腐烂度,它的值等于牛从开始到吃它位置的时间,牛想把所有草吃完之后,腐烂值的总和最小
题解
先对坐标进行排序,然后就进行DP,方程和BZOJ2037是一样的~~~
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 1005
int dp[2][MAXN][MAXN];
int x[MAXN];
int n,x0;
int main()
{
scanf("%d%d",&n,&x0);
for(int i=1;i<=n;i++)
scanf("%d",&x[i]);
x[++n]=x0;
sort(x+1,x+n+1);
for(int i=1;i<=n;i++)
if(x[i]!=x0)dp[0][i][i]=dp[1][i][i]=INF;
else
dp[0][i][i]=dp[1][i][i]=0;
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++)
{
dp[0][i][j]=min(dp[0][i+1][j]+(x[i+1]-x[i])*(n-j+i),
dp[1][i+1][j]+(x[j]-x[i])*(n-j+i));
dp[1][i][j]=min(dp[1][i][j-1]+(x[j]-x[j-1])*(n-j+i),
dp[0][i][j-1]+(x[j]-x[i])*(n-j+i));
}
printf("%d\n",min(dp[0][1][n],dp[1][1][n]));
return 0;
}
ZOJ3469 Food Delivery
题目大意
和上题没啥区别。。。
有n个人叫餐,每个人都在x轴上,并且每个人都有个坑爹度(和等餐时间有关,据说顾客认为坑爹值到一定程度他的小宇宙就要爆发).现在送餐员从x轴上的某点出发,路上奔跑速度是v,要一次性把所有餐送完。叫餐的人得到餐的时间和顺序不同,坑爹度总和也就不同
题解
同上。。。
代码:
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 1005
#define x first
#define y second
#define INF 0x3f3f3f3f
int dp[2][MAXN][MAXN];
int sum[MAXN];
bool visit[MAXN][MAXN];
pair<int,int>a[MAXN];
int n,v,x0;
void dfs(int l,int r)
{
if(visit[l][r]) return;
if(l==r)
{
if(a[l].x==x0)dp[0][l][r]=dp[1][l][r]=0;
else
dp[0][l][r]=dp[1][l][r]=INF;
return;
}
visit[l][r]=true;
dfs(l+1,r);
dfs(l,r-1);
dp[0][l][r]=min(dp[0][l+1][r]+(a[l+1].x-a[l].x)*(sum[n]-sum[r]+sum[l]),
dp[1][l+1][r]+(a[r].x-a[l].x)*(sum[n]-sum[r]+sum[l]));
dp[1][l][r]=min(dp[1][l][r-1]+(a[r].x-a[r-1].x)*(sum[n]-sum[r-1]+sum[l-1]),
dp[0][l][r-1]+(a[r].x-a[l].x)*(sum[n]-sum[r-1]+sum[l-1]));
}
int main()
{
while(scanf("%d%d%d",&n,&v,&x0)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
a[++n].x=x0;
a[n].y=0;
sort(a+1,a+n+1);
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i].y;
memset(visit,false,sizeof(visit));
dfs(1,n);
printf("%d\n",v*min(dp[0][1][n],dp[1][1][n]));
}
return 0;
}
费用提前计算相关的DP(BZOJ2037,POJ3042,ZOJ3469)的更多相关文章
- POJ 3042 区间DP(费用提前计算相关的DP)
题意: 思路: f[i][j][1]表示从i到j的区间全都吃完了 现在在j点 变质期最小是多少 f[i][j][0]表示从i到j的区间全都吃完了 现在在i点 变质期最小是多少 f[i][j][0]=m ...
- 【BZOJ2037】[Sdoi2008]Sue的小球 区间DP+费用提前
[BZOJ2037][Sdoi2008]Sue的小球 Description Sue和Sandy最近迷上了一个电脑游戏,这个游戏的故事发在美丽神秘并且充满刺激的大海上,Sue有一支轻便小巧的小船.然而 ...
- BZOJ-2037 Sue的小球 DP+费用提前
似乎很早时学长考过很类似的? 2037: [Sdoi2008]Sue的小球 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 558 Solved: 300 ...
- BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
2726: [SDOI2012]任务安排 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 868 Solved: 236[Submit][Status ...
- [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算
题解 本题的状态很容易设计: f[i] 为到第i个物件的最小代价. 但是方程不容易设计,因为有"后效性" 有两种方法解决: 1)倒过来设计动态规划,典型的,可以设计这样的方程: d ...
- 通过IP地址和子网掩码与运算计算相关地址
通过IP地址和子网掩码与运算计算相关地址 知道IP地址和子网掩码后可以算出 网络地址 广播地址 地址范围 本网有几台主机 例一:下面例子IP地址为192.168.100.5 子网掩码是255.255. ...
- zoj 3469 Food Delivery 区间dp + 提前计算费用
Time Limit: 2 Seconds Memory Limit: 65536 KB When we are focusing on solving problems, we usual ...
- UVA - 1625 Color Length[序列DP 提前计算代价]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- 洛谷P1220关路灯[区间DP 提前计算代价]
题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村 ...
随机推荐
- CMOS (1)–PMOS与NMOS
1,名称来源 p,n指示的是生成的沟道类型 2,驱动逻辑0与逻辑1 一般用NMOS驱动逻辑0,用PMOS驱动逻辑1.
- hibernate持久化操作注意
15:05 2014/5/21 1.设置lazy为false可以立即加载配合get,lazy默认true,配合load使用. 2.把pojo类定义为final的类.为最终就可以不使用代理 3.pojo ...
- Memcached(六)Memcached的并发实例
package com.sinosuperman.memcached; import java.io.IOException; import java.net.InetSocketAddress; i ...
- Javascript事件传播
MicroSoft的设计是当事件在元素上触发时,该事件将接着在该节点的父节点触发,以此类推,事件一直沿着DOM树向上传播,直到到达顶层对象document元素.这种自底向上的事件传播方式称为" ...
- hex(x) 将整数x转换为16进制字符串
>>> a = 122 >>> b = 344 >>> c = hex(a) >>> d = hex(b) >>&g ...
- BZOJ 3953 Self-Assembly 解题报告
首先,我们可以先考虑一个暴力一点的算法: 对于任意两个分子,如果它们能以至少一种进行匹配,那么我们就在这两个分子之间连一条边. 然后如果我们能找到一个环,就说明是 unbounded,否则就是 bou ...
- BZOJ 3983 Takeover Wars 解题报告
我猜了一个结论,能合并就合并,到了必须要敌对交易的时候才进行敌对交易. 然后合并的话,肯定是拿最大的两个去合并. 至于敌对交易,肯定是干掉对方最大的公司才是有意义的. 于是各种分类讨论...看代码好了 ...
- jsp接收相同复合参数 request.getParameterValues()用法
在网站中往往需要用户选择复选框,此时需要创建多个复选框让用户进行选择: <head> <meta http-equiv="Content-Type" conten ...
- SPRING IN ACTION 第4版笔记-第五章BUILDING SPRING WEB APPLICATIONS-002-Controller的requestMapping、model
一.RequestMapping 1.可以写在方法上或类上,且值可以是数组 package spittr.web; import static org.springframework.web.bind ...
- Visual Studio 那些隐藏的调试功能(转)
原文出处: 微软互联网开发支持 Visual Studio 是一个强大的调试工具,里面很多隐藏功能少有人问津,但是在特定场景可以节省你很多时间,本文主要介绍一些Visual Studio调试相关 ...