http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1105
1105: 打怪升級
Time Limit: 1 Sec Memory Limit: 64 Mb Submitted: 357 Solved: 104Description
Input
輸入最多包含25組測試數據。每組數據第一行爲兩個整數n和p(1<=n<=1000, 1<=p<=100),即戰鬥的場數和你的初始力量值。以下n行每行6個整數p1, p2, t1, t2, w1, w2(1<=p1<p2<=100, 1<=t2<t1<=100, 0<=w1,w2<=10),按順序給出各場戰鬥的參數。輸入結束標誌爲n=p=0。
Output
對於每組數據,輸出最短總時間(單位:秒),保留兩位小數。如果無解,輸出“Impossible”(不含引號)。
Sample Input
1 55 50 75 40 15 10 0 2 55 50 75 40 15 10 0 50 75 40 15 10 0 3 1 1 2 2 1 0 5 1 2 2 1 1 0 1 100 100 1 0 0 1 7 4 15 35 23 0 0 1 1 2 3 2 1 0 0 0 0
Sample Output
35.00 60.00 41.00 31.73 Impossible
Hint
Source
湖南省第七屆大學生計算機程序設計競賽思路:可以知道,+1只要有就直接吃,*2可以等等吃。然後力量大於100以後是無敵的,所以不會有很多狀態,看到很多博客都是dfs,我用的是bfs。
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 1005
int p1[maxn], p2[maxn], t1[maxn], t2[maxn], w1[maxn], w2[maxn];
int n,p;
struct node
{
int now;
int p;
double ti;
int h2;
node() {}
node(int a,int b,double c,int e)
{
now=a;
p=b;
ti=c;
h2=e;
}
};
struct CMP
{
bool operator()(node a,node b)
{
return a.ti>b.ti;
}
};
void bfs()
{
priority_queue<node ,vector<node >, CMP > q;
while(!q.empty())
{
q.pop();
}
q.push(node(1,p,0,0));
int f=0;
while(!q.empty())
{
node k=q.top();
q.pop();
if(k.now==n+1)
{
f=1;
printf("%.2f\n",k.ti);
break;
}
int pos=k.now;
if(k.p<p1[pos]) continue;
node c;
c.p=k.p+w1[pos];
c.now=k.now+1;
c.h2=k.h2+w2[pos];
if(k.p>p2[pos])
{
c.ti=k.ti+t2[pos];
}
else
{
c.ti=k.ti+1.0*(1.0*p1[pos]*t2[pos]-1.0*p2[pos]*t1[pos]-(1.0*(t2[pos]-t1[pos])*k.p))/(1.0*p1[pos]-p2[pos]);
}
if(c.p<100)
{
q.push(c);
int num=c.h2;
for(int i=0; i<num; i++)
{
c.p=c.p*2;
c.h2--;
q.push(c);
if(c.h2<=0) break;
}
}
else
{
q.push(c);
}
}
if(!f)
{
printf("Impossible\n");
}
}
int main()
{
while(~scanf("%d%d",&n,&p)&&n+p)
{
for(int i=1; i<=n; i++)
{
scanf("%d%d%d%d%d%d",&p1[i],&p2[i],&t1[i],&t2[i],&w1[i],&w2[i]);
}
bfs();
}
return 0;
}