lightoj-1381 - Scientific Experiment dp

来源:互联网 发布:梦幻邮箱数据 编辑:程序博客网 时间:2024/05/16 15:13

John wants to be a scientist. A first step of becoming a scientist is to perform experiment. John has decided to experiment with eggs. He wants to compare the hardness of eggs from different species. He has decided to use a nearby large multi-storied building for this purpose. For each species he will try to find the highest floor from which he can drop the egg and it will not break. The building has (n+1) floors numbered from 0 to n. John has a book from which he knows that

1.      aIf an egg is dropped from the topmost floor, it will surely break.

2.      If an egg is dropped from floor 0, it will not break.

3.      The eggs of same species are of same strength. That means if any egg breaks when dropped from the kth floor; all the eggs of that species will break if dropped from kth floor.

4.      If an egg is unbroken after dropping it from any floor, it remains unharmed, that means the strength of the egg remains same.

Unfortunately John has a few problems:

1.      He can only carry one egg at a time.

2.      He can buy eggs from a shop inside the building and an egg costs x cents.

3.      To enter the building he has to pay y cents if he has no egg with him and z cents if he carries an egg with him.

4.      After dropping an egg, John must go outside the building to check whether it's broken or not.

5.      He does not want to waste any egg so he will not leave any unbroken egg on the ground. But if an egg is broken, he leaves it there.

6.      If he has an intact egg at the end, he can sell it for x/2 cents. He does not need to enter the building to sell the egg.

These problems are not going to tame John's curious mind. So he has decided to use an optimal strategy and minimize his cost in worst case. As John is not a programmer, he asked your help.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with a line containing four integers n x y z as described in the statement. You may assume that 1 < n ≤ 1000 and 1 ≤ x, y, z ≤ 105and x is even.

Output

For each test case, print the case number and the minimized worst case cost.

Sample Input

Output for Sample Input

7

4 2 998 1000

16 2 1000 1000

16 1000 1 1

4 1000 1 1

7 2 2 2

9 2 1 100

11 2 100 1

Case 1: 2000

Case 2: 4008

Case 3: 1015

Case 4: 1003

Case 5: 10

Case 6: 24

Case 7: 111

Note

For case 1, John knows that the egg will break if dropped from 4th floor, but will not break if dropped from 0th floor. An optimal solution may be

1.      John enters the building without any egg (¢998).

2.      John buys an egg (¢2).

3.      John drops an egg from 2nd floor. John goes out and checks the egg.

a.       If it breaks,

                                                              i.      John again enters the building without any egg (¢998) and buys an egg there ¢2.

                                                            ii.      He drops the egg from 1st floor.

1.      If it does not break then answer to his problem is 1 and he can sell the egg for ¢1. So his final cost in ¢1999.

2.      If it breaks then the answer to his problem is 0th floor and his final cost is ¢2000.

b.      If it does not break

                                                              i.      John enters the building with the egg (¢1000).

                                                            ii.      He drops it from 3rd floor.

1.      If it does not break then answer to his problem is 3 and he can sell the egg for ¢1. So his final cost in ¢1999.

2.      If it breaks then the answer to his problem is 2 and final cost is ¢2000.

So, using this strategy, his worst case cost is ¢2000.


注意从最高层楼扔下来鸡蛋是一定会碎的。

设dp[i]为i层楼测鸡蛋硬度的最小花费,考虑在j层扔下一枚鸡蛋,

1.如果摔碎了,那么花费则是dp[j] + x + y;

2.如果没摔碎,那么花费则是dp[i-j] + x + y + z - x- y = dp[i-j] + z;

3.如果j = i - 1,则2中的花费应为dp[i-j] + y + x / 2;


#include <bits/stdc++.h>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define ll long long#define SZ(x) ((int)(x).size()) #define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i) #define REP(i,a,n) for ( int i=a; i<int(n); i++ )#define FOR(i,a,n) for ( int i=n-1; i>= int(a);i-- )#define lson rt<<1, L, m#define rson rt<<1|1, m, Rtypedef pair<int, int> pii;typedef pair<ll, ll> pll;#define mp(x, y) make_pair(x, y)#define pb(x) push_back(x)#define fi first#define se second#define CLR(a, b) memset(a, b, sizeof(a))#define Min(a, b) a = min(a, b)#define Max(a, b) a = max(a, b)const int maxn = 1e3 + 7;const ll INF = 0x3f3f3f3f3f3f3f3f;int T;int kase;int n;ll x, y, z;ll dp[maxn];ll solve(){    //CLR(dp, INF);    dp[0] = dp[1] = 0;    REP(i, 2, n + 1){        dp[i] = INF;        REP(j, 1, i){            ll a = dp[j] + x + y;            ll b = dp[i-j] + z;            if(j == i - 1) b = dp[i-j] + y + x / 2;            Min(dp[i], max(a, b));        }    }    return dp[n];}int main(){#ifdef ac    freopen("in.txt","r",stdin);#endif    //freopen("out.txt","w",stdout);    scanf("%d", &T);    while(T--){        scanf("%d%lld%lld%lld", &n, &x, &y, &z);        printf("Case %d: %lld\n", ++kase, solve());    }    return 0;}



0 0