Uva 10688 The Poor Giant (区间DP)

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

5
2 0
3 0
4 0
5 0
10 20
Case 1: 2
Case 2: 6
Case 3: 13
Case 4: 22
Case 5: 605

题意就不说了。

思路: dp[i][j] 表示第i个到第j个的最佳方案下的总重量。

dp[i][j]  =  min( dp[i][t-1]+dp[t+1][j]+(t+m)*(j+1-i)
)  (i <= t <= j)(注意边界);

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf=99999999;
const int maxn=550;

int dp[maxn][maxn],n,m;

void initial()
{
    memset(dp,0,sizeof(dp));
}

void input()
{
    scanf("%d %d",&n,&m);
}

void solve(int co)
{
    for(int k=2; k<=n; k++)
        for(int i=1,j=i+k-1; j<=n; j++,i++)
        {
            int ans=inf,tmp;
            for(int t=i; t<=j; t++)
            {
                tmp=(m+t)*k;
                if(t!=i) tmp+=dp[i][t-1];
                if(t!=j) tmp+=dp[t+1][j];
                ans=min(ans,tmp);
            }
            dp[i][j]=ans;
        }
    printf("Case %d: %d\n",co,dp[1][n]);
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int co=1; co<=T; co++)
    {
        initial();
        input();
        solve(co);
    }
    return 0;
}
时间: 2024-10-13 18:42:14

Uva 10688 The Poor Giant (区间DP)的相关文章

uva live 3516 Exploring Pyramids 区间DP

// uva live 3516 Exploring Pyramids 区间DP // // 题目大意: // // 给你一个多叉树,每个节点是一个大写字母,从根节点走,按照先序遍历的 // 原则访问,不能访问则回溯,每次记录一下节点的字符,最后得到一个字符串.现 // 在给你一个字符串,问可能符合条件的多叉树的数量. // // 解题思路: // // 区间DP,我们注意到,从根节点出发,一定会再次回到根节点,那么我们可以设 // d(i,j) 是序列i到j段形成的符合条件的多叉树的数量,则

uva 10529 - Dumb Bones(概率+区间dp)

题目连接:uva 10529 - Dumb Bones 题目大意:给定n,表示要放n个骨牌,每次放下骨牌,有可能向左倒的概率为pl,向右倒的概率为pr,如果倒下,会将那一侧的骨牌全部推倒,可以选择位置先后放骨牌,问说一种放骨牌次数最少的期望是多少. 解题思路:dp[i]表示放i个骨牌需要的步数期望,维护一个最优放的位置,dp[i] = min\{ (从i-1到i的步数)} + (0到i-1的步数)} (从i-1到i的步数):dp[i?j?1]?pl+dp[j]?pr+11?pl?pr (0到i-

uva 10003 Cutting Sticks 简单区间dp

// uva 10003 Cutting Sticks 区间dp // 经典的区间dp // dp(i,j)表示切割小木棍i-j所需要的最小花费 // 则状态转移为dp(i,j) = min{dp(i,k) + dp(k,j) + a[j]-a[i]) // 其中k>i && k<j // a[j] - a[i] 为第一刀切割的代价 // a[0] = 0,a[n+1] = L; // dp数组初始化的时候dp[i][i+1]的值为 0,这表示 // 每一段都已经是切割了的,不

uva 10003 Cutting Sticks 【区间dp】

题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,其实和石子归并是一样的,花费就是石子的和,那么久不用多说了. AC代码: #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include <map> #include <

UVA 10891 Game of Sum 区间dp

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 题目意思大致是给你一串数字,A,B两个人轮流从两端取一段数字并得到该串数字的和的点数,每个人都尽可能的多的点数,问A最多能比B多多少点. 区间dp,一开始打算分AB,但是发现太麻烦了,最后用dp(l,r)表示在区间l~r中先手能赢的的最多点数.假设A是区间(l,r)的先手的话,如果A选择了(l,k )// 或(k+1,r)的数字,那他的得分(l,r)的总分减去B在余

uva live 4394 String painter 区间dp

// uva live 4394 String painter // // 这一题是训练指南上dp专题的习题,初看之下认为仅仅是稍微复杂了一点 // 就敲阿敲阿敲,两个半小时后,发现例子过了.然而自己给出的数据跪了 // 交了也wa了,才发现,自己的方法是有问题的,假设是将两个串同一时候考虑 // 的话,比方: dp[i][j] 表示从i到j,s串刷成目标b串所须要的最小的花费 // 然后依据区间的端点的字符特点,进行状态转移,然而可能是我太搓了, // 发现这种状态转移是不正确的.比方edc和

uva 10453 Make Palindrome (区间DP + 递归输出)

uva 10453 Make Palindrome 题目大意:给出一段字符串,要求求出最少加入几个字符(任意位置),可以让该字符串变成会问字符串,并输出修改以后的回文字符串. 解题思路:dp[i][j]代表了将该字符串从第i位到第j位变成回文字符串最少要添加的字符.当S[i]==S[j],dp[i][j]=dp[i+1][j?1]当S[i]!=S[j],dp[i][j]=min(dp[i+1][j],dp[i][j?1])+1,在DP的过程中记录对该区间的操作类型,最后递归输出. #includ

UVA 4394 - String painter(字符串区间DP)

String painter                           Time Limit:3000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu Description There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string

uva 10891 sum游戏(区间dp)

 给定n个数字,A和B可以从这串数字的两端任意选数字,一次只能从一端选取.并且A B都尽力使自己选择的结果为最大的,可以理解成A B每一步走的都是最优的.如果A先选择,则A B差值最大是多少. 思路:用d[i][j]表示当前选手先手走能获得的最大总分数,由于总的分数是一定的,那么状态转移方程为 d[i][j] = sum(i, j) - min( minleft(i+1, j), minright(i, j-1), 0) 其中minleft(i, j)表示min(d[i][j], d[i+1