CSU 1105

A - 打怪升級
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu
Appoint description: 

Description

對於多數RPG遊戲來說,除了劇情就是打怪升級。本題的任務是用最短的時間取得所有戰鬥的勝利。這些戰鬥必須按照特定的順序進行,每打贏一場,都可能會獲得一些補藥,用來提升力量。本題只有兩種補藥:“加1藥”和“乘2藥”,分別讓你的力量值加1和乘以2。
戰鬥時間取決於你的力量。每場戰鬥可以用6個參數描述:p1, p2, t1, t2, w1, w2。如果你的力量小於p1,你將輸掉戰鬥;如果你的力量大於p2,需要t2秒贏得戰鬥;如果力量位於p1和p2(包括p1和p2),戰鬥時間從t1線性遞減到t2。比如p1=50,p2=75,t1=40,t2=15,你的力量爲55,則戰鬥獲勝需要35秒。注意,戰鬥時間可能不是整數。最後兩個參數w1和w2分別表示戰鬥勝利後獲得的“加1藥”和“乘2藥”的數量。注意,你不一定要立刻使用這些補藥,可以在需要的時候再用,但不能在戰鬥中使用補藥。
按順序給出每場戰鬥的參數,輸出贏得所有戰鬥所需的最短總時間。戰鬥必須按順序進行,且不能跳過任何一場戰鬥。

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 
分析:剛開始以爲是模擬,直接上測數據發現不對,後來才知道模擬搞不定,必須枚舉在開始下一場戰鬥前吃“乘2血”的瓶數,而對於“加1血”當前有多少瓶全吃掉是最優的。
記憶化搜索
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>


#include <algorithm>
using namespace std;
const double INF=99999999.0;
int n,p;
struct node
{
  int p1,p2,t1,t2,w1,w2;
}st[1100];

double dp[1100][110][15]; //dp[n][s][num] 表示進行第n-1場戰鬥剛結束,體力值爲s,帶num瓶乘2血瓶到達目標狀態的最小時間


double cal(int s,int x)
{
   if(s>=st[x].p2)
          return  st[x].t2;
   double k=1.0*(st[x].t1-st[x].t2)/(st[x].p1-st[x].p2);
   double b=st[x].t1-k*st[x].p1;
   return 1.0*k*s+b;

}

double dfs(int x,int s,int num)
{
    if(x>n)return 0;
    if(dp[x][s][num]>-1)return dp[x][s][num];
    
        while(s<st[x].p1 && num)
        {
        s=min(100,s*2);
        num--;
        }
    

    if(s<st[x].p1)
    {
       dp[x][s][num]=INF;
       return INF;
    }

    dp[x][s][num]=INF;
    for(int i=0;i<=num;i++)
    {
        int ss=s<<i;
        double t=cal(ss,x);
        dp[x][s][num]=min(dp[x][s][num],t+dfs(x+1,min(100,ss+st[x].w1),min(10,num-i+st[x].w2)));
    }
    return dp[x][s][num];
}

int main()
{
   while( cin>>n>>p )
   {
      if( n==0 && p==0 ) break;
      for(int i=1;i<=n;i++)
        scanf("%d%d%d%d%d%d",&st[i].p1,&st[i].p2,&st[i].t1,&st[i].t2,&st[i].w1,&st[i].w2);

      memset(dp,-1,sizeof(dp));

      double ans=dfs(1,p,0);
      if(ans==INF)
         printf("Impossible\n");
      else
         printf("%.2lf\n",ans);
   }
   return 0;
}



發佈了244 篇原創文章 · 獲贊 17 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章