UVa 10688 The Poor Giant(区间DP)

来源:互联网 发布:impress.js reveal.js 编辑:程序博客网 时间:2024/05/22 10:31

Problem A

The Poor Giant

Input: Standard Input

Output: Standard Output

Time Limit: 1 second

On a table, there are n apples, the i-th apple has the weight k+i(1<=i<=n). Exactly one of the apples is sweet, lighter apples are all bitter, while heavier apples are all sour. The giant wants to know which one is sweet, the only thing he can do is to eat apples. He hates bitter apples and sour apples, what should he do?
For examples, n=4, k=0, the apples are of weight 1, 2, 3, 4. The gaint can first eat apple #2.
if #2 is sweet, the answer is #2
if #2 is sour, the answer is #1
if #2 is bitter, the answer might be #3 or #4, then he eats #3, he'll know the answer regardless of the taste of #3
The poor gaint should be prepared to eat some bad apples in order to know which one is sweet. Let's compute the total weight of apples he must eat in all cases.
#1 is sweet: 2
#2 is sweet: 2
#3 is sweet: 2 + 3 = 5
#4 is sweet: 2 + 3 = 5
The total weights = 2 + 2 + 5 + 5 = 14.
This is not optimal. If he eats apple #1, then he eats total weight of 1, 3, 3, 3 when apple #1, #2, #3 and #4 are sweet respectively. This yields a solution of 1+3+3+3=13, beating 14. What is the minimal total weight of apples in all cases?

Input

The first line of input contains a single integer t(1<=t<=100), the number of test cases. The following t lines each contains a positive integer n and a non-negative integer k(1<=n+k<=500).

Output

For each test case, output the minimal total weight in all cases as shown in the sample output.

Sample Input

Sample Output

52 03 04 05 010 20
Case 1: 2Case 2: 6Case 3: 13Case 4: 22Case 5: 605


Problem setter: Rujia Liu, Member of Elite Problemsetters' Panel


题目大意:

有n个苹果,和一个数k,第i个苹果的重量是k+i(1<=i<=n). 已知其中只有一个苹果是甜的,所有比它重量轻的都是苦的,比它重的都是酸的。为了要找出甜的苹果,就要去一个一个地吃它,且吃了咬了苹果就必须把它吃完,不管苹果是苦的还是酸的。
(题目描述有误)
例如,先吃#1, 
如果#1是甜的,花费1
如果#2是甜的,那么选择吃#3,不管#3是什么味道,都可以推测出#2和#4的味道,那么花费1+3
如果#3是甜的,第二次选择吃#3, 共花费1+3 = 4
如果#5是甜的,方案和上面一样, 共花费1+3 = 4
总共1+4+4+4 = 13,这方案更好。

给出n和k,问最少的吃的苹果总重量是多少?


解题思路:

区间DP。用dp[l][r]表示区间[l,r]中采用最佳策略要吃的苹果总重量。

状态转移方程:dp[l][r] = min( dp[l][i-1] + dp[i+1][r] + (i+k)*(r-l+1) )   (l <= i <= r)

其中(r-l+1)为区间长度,如果当前决策选择i吃下后,之后的选择都会多出(i+k),所以转移加上(i+k)*(r-l+1)。

可以考虑区间长度为2时,只会选择左端的。长度为3时,必然选择中间的。但不考虑也可以,已包含在状态转移方程中。


参考代码:

#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAXN = 510;const int INF = 0x3f3f3f3f;int nCase, cCase, n, k, dp[MAXN][MAXN];void init() {    memset(dp, -1, sizeof(dp));}void input() {    scanf("%d%d", &n, &k);}int DP(int l, int r) {    if (l > r) return 0;    if (dp[l][r] != -1) return dp[l][r];    if (l == r) return dp[l][r] = 0;    //if (l + 1 == r) return dp[l][r] = (l+k)*2;    //if (l + 2 == r) return dp[l][r] = (l+k)*3+3;    int ret = INF;    for (int i = l; i <= r; i++) {        ret = min(ret, DP(l, i-1) + DP(i+1, r) + (i+k)*(r-l+1));    }    return dp[l][r] = ret;}void solve () {    printf("Case %d: %d\n", ++cCase, DP(1, n));}int main() {    scanf("%d", &nCase);    while (nCase--) {        init();        input();        solve();    }    return 0;}


0 0