1. 程式人生 > >poj 2904 The Mailboxes Manufacturers Problem(DP)

poj 2904 The Mailboxes Manufacturers Problem(DP)

The Mailboxes Manufacturers Problem
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 947 Accepted: 685

Description

In the good old days when Swedish children were still allowed to blowup their fingers with fire-crackers, gangs of excited kids would plague certain smaller cities during Easter time, with only one thing in mind: To blow things up. Small boxes were easy to blow up, and thus mailboxes became a popular target. Now, a small mailbox manufacturer is interested in how many fire-crackers his new mailbox prototype can withstand without exploding and has hired you to help him. He will provide you withk

(1 ≤ k ≤ 10) identical mailbox prototypes each fitting up to m (1 ≤m ≤ 100) crackers. However, he is not sure of how many firecrackers he needs to provide you with in order for you to be able to solve his problem, so he asks you. You think for a while and then say, “Well,if I blow up a mailbox I can’t use it again, so if you would provide me with only k
= 1 mailboxes, I would have to start testing with 1 cracker, then 2 crackers, and so on until it finally exploded. In the worst case, that is if it does not blow up even when filled with m crackers, I would need 1 + 2 + 3 + … + m = m × (m + 1) ⁄ 2 crackers. Ifm = 100 that would mean more than 5000 fire-crackers!” “That’s too many,” he replies. “What if I give you more thank
= 1 mailboxes? Can you find a strategy that requires less crackers?”

Can you? And what is the minimum number of crackers that you should ask him to provide you with?

You may assume the following:

  1. If a mailbox can withstand x fire-crackers, it can also withstand x − 1 fire-crackers.
  2. Upon an explosion, a mailbox is either totally destroyed (blown up) or unharmed, which means that it can be reused in another test explosion.

Note: If the mailbox can withstand a full load of m fire-crackers, then the manufacturer will of course be satisfied with that answer. But otherwise he is looking for the maximum number of crackers that his mailboxes can withstand.

Input

The input starts with a single integer N (1 ≤ N ≤ 10) indicating the number of test cases to follow. Each test case is described by a line containing two integers:k andm, separated by a single space.

Output

For each test case print one line with a single integer indicating the minimum number of fire-crackers that is needed, in the worst case, in order to figure out how many crackers the mailbox prototype can withstand.

Sample Input

4
1 10
1 100
3 73
5 100

Sample Output

55
5050
382
495
題意:給出k個完全相同郵筒,每個郵筒理論上能承受的火藥量為m。現在要測試這些郵筒的實際能承受的火藥量是否真的為m,則需要多少數量的火藥。如果在測試過程中郵筒爆破了,則不能繼續使用這個郵筒,如果郵筒完好無損,則下一次實驗能繼續使用。所以只有一個郵筒時,則需要從1到m逐個去試驗,這樣的話就算那個郵筒爆破了,也能知道它實際的承受火藥量。但是如果給出多於1個郵筒,則可以直接從t>=1開始試驗,因為就算一個郵筒爆破了,還有另外的郵筒供試驗。
思路:當只有一個郵筒時,需要的火藥顯然為1+2+3+...+m,這樣才能測出郵筒的實際能承受的火藥量。但是當給出郵筒數增多時,則不需要那麼多的火藥。設dp[k][i][j]表示給出k個郵筒,承受火藥量試驗範圍為[i,j]時所需的火藥數量。
設給出k個郵箱,第一次測試t的火藥數量,有兩種情況:
(1)若郵筒爆破了,則下次測試範圍為[i,t-1],所需火藥量為dp[k-1][i][t-1];
(2)若郵筒完好無損,則下次測試範圍為[t+1,j],所需火藥量為dp[k][t+1][j].  (若郵筒完好無損,則能繼續使用)
因為不知道郵筒是否會爆破,所以要作最壞打算,從上面兩種情況中選擇所需火藥量最大的情況,列舉t,在這些最大的情況中選擇所需火藥量最少的。
AC程式碼:
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <iostream>
#define max2(a,b) ((a) > (b) ? (a) : (b))
#define min2(a,b) ((a) < (b) ? (a) : (b))

using namespace std;

const int INF=10000000;
int main()
{
    int dp[15][105][105];
    for(int i=1;i<=100;i++)
    for(int j=i;j<=100;j++)
    dp[1][i][j]=(j-i+1)*(i+j)/2;

    for(int k=2;k<=10;k++)
    for(int j=100;j>=1;j--)
    for(int i=j;i>=1;i--)
    {
        dp[k][i][j]=INF;
        for(int t=i;t<=j;t++)
        dp[k][i][j]=min(dp[k][i][j],t+max(dp[k-1][i][t-1],dp[k][t+1][j]));
    }
    int k,m,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&k,&m);
        printf("%d\n",dp[k][1][m]);
    }
    return 0;
}