您的位置:首页 > 其它

UVa 10201 Adventures in Moving(简单DP)

2012-11-21 12:06 411 查看
题意:

有一辆车,原始装有100L汽油,到达距离为d的目的地,中间有x个加油站,每升油的价格为p。

汽车每跑一公里耗油1L,求到达目的地油箱仍然有100L的最小花费。

思路:

动归方程算是简单的,主要是要思考清楚,在第i个加油站加不加油,如果加油加k升的最小花费。

dp[i, j]表示在第i个加油站油箱有j升油的最小花费:

1. 在i站不加油 dp[i, j] = dp[i-1, j+di]; di为i-1到i的距离

2. 在i站加k升油 dp[i][j] = min(dp[i][j], dp[i-1][j-k+di] + k * p[i]);

初始状态为:dp[0, 100] = 0 其它的都是不可到达状态,赋值int_max

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;

int dp[110][210];
int d[110], p[110];
char str[100];
int dis, n;

void init_input()
{
gets(str);
sscanf(str, "%d", &dis);
n = 0;
d[0] = 0;
while (gets(str) != NULL)
{
if (str[0] == '\0')
break;
++n;
sscanf(str, "%d %d", &d
, &p
);

if (d
> dis) --n;
}
}

void solve_dp()
{
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= 200; ++j)
dp[i][j] = INT_MAX;
dp[0][100] = 0;

for (int i = 1; i <= n; ++i)
{
int w = d[i] - d[i-1];

for (int j = 0; j + w <= 200; ++j)
if (dp[i-1][j+w] != INT_MAX)
dp[i][j] = dp[i-1][j+w];

for (int j = 0; j <= 200; ++j)
for (int k = 0; k <= j; ++k)
if (j-k+w <= 200 && dp[i-1][j-k+w] != INT_MAX)
dp[i][j] = min(dp[i][j], dp[i-1][j-k+w] + k * p[i]);
}

if (100 < dis - d
|| dp
[100+dis-d
] == INT_MAX)
printf("Impossible\n");
else
printf("%d\n", dp
[100+dis-d
]);
}

int main()
{
int cases;
gets(str);
sscanf(str, "%d", &cases);
gets(str);
while (cases--)
{
init_input();
solve_dp();
if (cases)
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: