您的位置:首页 > 其它

Fixing the Great Wall UVA - 1336(区间dp+前缀和)

2017-08-14 15:48 337 查看
题目连接;点击打开链接
题目大意:给出n个坏掉的东西的坐标,和 初始花费,以及增长速度,给出机器人的速度和初始坐标,问最少花费能修好全部东西。

题目思路:很容易知道机器人修理好的东西一定是一个连续的区间,并且每一次都会有不同的决策们很容易知道是dp,我们定义状态dp[i][j]为修理好了i到j需要的最少花费,

接下来很容易发现还需要知道机器人在区间的哪一端,所以我们定义状态dp[i][j][2],为修好了i到j机器人在最左端和最右端最小花费,然后从机器人起点往外扩展就行了,

这里有个技巧就是吧起点也当作一个坏掉的东西处理,接下来还有一个烦人的就是怎么往外扩展,用记搜当然可以,不过还是递推比较方便,详情看代码

ac代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstring>
#include<iostream>
#include<sstream>
#include<cmath>
#include<vector>
#define LL long long
#define INF 0x3f3f3f3f
#define eps 1e-6
#include<deque>
using namespace std;
const int maxn = 1e9+5;
double dp[1005][1005][2];
int sum[1005];
int sum2[1005];
struct node
{
int pos;
int cost;
int ic;
}E[1005];
int n,v,x;
int cmp(node a,node b)
{
return a.pos<b.pos;
}
int main()
{
while(~scanf("%d%d%d",&n,&v,&x)){
if(n+v+x==0)
return 0;
for(int i = 0;i<=n+1;i++){
for(int j = 0;j<=n+1;j++){
dp[i][j][0] = (double)maxn;
dp[i][j][1] = (double)maxn;
}
}
E[n+1].pos = x;
E[n+1].cost = E[n+1].ic = 0;
for(int i = 1;i<=n;i++){
scanf("%d%d%d",&E[i].pos,&E[i].cost,&E[i].ic);
}
sort(E+1,E+n+2,cmp);
for(int i = 1;i<=n+1;i++){
sum[i] = sum[i-1] + E[i].ic;
}
for(int i = 1;i<=n+1;i++){
sum2[i] = sum2[i-1]+E[i].cost;
}
int s;
for(int i = 1;i<=n+1;i++){
if(E[i].pos == x){
s = i;
break;
}
}
dp[s][s][0] = dp[s][s][1] = 0;
for(int i = s;i>=1;i--){
for(int j = s;j<=n+1;j++){
if(i>1){
double t = abs(E[j].pos-E[i-1].pos)*1.0/v;
dp[i-1][j][0] = min(dp[i-1][j][0],dp[i][j][1]+E[i-1].cost+t*(sum[i-1]+sum[n+1]-sum[j]));
t = abs(E[i].pos-E[i-1].pos)*1.0/v;
dp[i-1][j][0] = min(dp[i-1][j][0],dp[i][j][0]+E[i-1].cost+t*(sum[i-1]+sum[n+1]-sum[j]));
}
if(j<n+1){
double t = abs(E[j+1].pos-E[j].pos)*1.0/v;
dp[i][j+1][1] = min(dp[i][j+1][1],dp[i][j][1]+E[j+1].cost+t*(sum[i-1]+sum[n+1]-sum[j]));
t = abs(E[j+1].pos-E[i].pos)*1.0/v;
dp[i][j+1][1] = min(dp[i][j+1][1],dp[i][j][0]+E[j+1].cost+t*(sum[i-1]+sum[n+1]-sum[j]));
}
// cout<<dp[i][j][0]<<' '<<i<<' '<<j<<endl;
//cout<<dp[i][j][1]<<' '<<i<<' '<<j<<endl;
}
}
printf("%d\n",(int)min(dp[1][n+1][0],dp[1][n+1][1]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM dp