UVA12294-RPG battles



题意:给你n和p,有n个敌人要打败,每个敌人有p1, p2, t1, t2, w1, w2, 代表如果你的p大于p2的话,那么将只花费t2秒,在p1和p2之间的话,就需要在t2到t1的线性比时间,w1代表力量加一药水的数量,w2代表力量翻倍药水的数量,要按顺序消灭敌人,求最短的时间。
解题思路:dp,设dp[i][j][k]表示第i个敌人,此时j的力量的,w2药水的数量。有加一的药水肯定立马用掉,但是翻倍的不能确定是否使用,所以需要记录起来,w2的最大值是不超过7,力量最大不超过100。


#include <iostream>   
#include <cstdio>   
#include <cstring>   
#include <string>   
#include <algorithm>   
#include <cmath>  
#include <map>   
#include <set>  
#include <stack>  
#include <queue>   
#include <vector>   
#include <bitset>   
#include <functional>   

using namespace std;

#define LL long long  
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;

double dp[1010][110][10];
int f[10];
int n, p, p1, p2, t1, t2, w1, w2;

void init()
{
	f[0] = 1;
	for (int i = 1; i < 10; i++) f[i] = f[i - 1] * 2;
}

double cal(int p1, int p2, int t1, int t2, int p)
{
	if (p >= p2) return t2;
	if (p < p1) return 1.0 * INF;
	return 1.0 * t1 - 1.0 * (t1 - t2) / (p2 - p1) * (p - p1);
}

int main()
{
	init();
	while (~scanf("%d %d", &n, &p))
	{
		if (!n && !p) break;
		for (int i = 0; i <= n; i++)
			for (int j = 0; j <= 105; j++)
				for (int k = 0; k <= 8; k++)
					dp[i][j][k] = 1.0 * INF;
		dp[0][p][0] = 0;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d %d %d %d %d %d", &p1, &p2, &t1, &t2, &w1, &w2);
			for (int j = 1; j <= 100; j++)
				for (int k = 0; k <= 7; k++)
					for (int l = 0; l <= k + w2; l++)
					{
						if (fabs(dp[i - 1][j][k] - 1.0 * INF) < eps) continue;
						int tmp1 = min(100, j + w1);
						int tmp2 = min(tmp1 * f[l], 100);
						int tmp3 = min(k + w2 - l, 7);
						dp[i][tmp2][tmp3] = min(dp[i][tmp2][tmp3], dp[i - 1][j][k] + cal(p1, p2, t1, t2, j));
					}
		}
		double ans = 1.0 * INF;
		for (int i = 1; i <= 100; i++)
			for (int j = 0; j <= 7; j++)
				ans = min(ans, dp[n][i][j]);
		if (fabs(ans - 1.0 * INF) < eps) printf("Impossible\n");
		else printf("%.2lf\n", ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值