您的位置:首页 > 其它

UVA 10201 Adventures in Moving - Part IV

2013-01-14 09:41 531 查看
大意不再赘述。

思路:d[i][j]表示到第i个加油站时,车厢内剩余油量为j时的最小消耗。

从i-1站到i站,要满足j+A[i].dis-A[j].dis <= 200且d[i][j] = d[i-1][j+A[i].dis-A[j].dis],对于当前站点的决策,即加油的最优值,k从0开始循环,保证j+k<=200即可,题目不保证加油站的距离一定比终点小,所以我们只截取距离<=de的加油站。取最大值时保证可以从最后一个加油站到达终点。即i >= 100+de-A
.dis即可。

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;

const int MAXN = 110; 
const int INF = 0x3f3f3f3f;

struct
{
	int dis, price;
}A[MAXN];

int n;
int de;

int d[110][210];

void init()
{
	n = 1;
	for(int i = 0; i < 110; i++)
	for(int j = 0; j < 210; j++)
	d[i][j] = INF;
	d[0][100] = 0;
}

int dp()
{
	for(int i = 1; i <= n; i++)
	{
		for(int j = 0; j <= 200; j++)
		{
			if(j + A[i].dis - A[i-1].dis <= 200)
			{
				int &st = d[i-1][j + A[i].dis - A[i-1].dis];
				for(int k = 0; j+k <= 200; k++)
				{
					d[i][j+k] = min(d[i][j+k], st+k*A[i].price);
				}
			}
		}
	}
	int ans = INF;
	for(int i = 100; i <= 200; i++)
	{
		if(i >= (100 + de - A
.dis) && d
[i] < ans) ans = d
[i];
	}
	return ans;
}

void read_case()
{
	char str[110];
	scanf("%d%*c", &de);
	while(gets(str))
	{
		if(str[0] == '\0') break;
		sscanf(str, "%d%d", &A
.dis, &A
.price);
		if(A
.dis <= de) n++;
	}
	--n;
}

void solve()
{
	init();
	read_case();
	int ans = dp();
	if(ans != INF) printf("%d\n", ans);
	else printf("Impossible\n");
}

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