hdu5543(Pick The Sticks) 01背包

Pick The Sticks

Time Limit: 15000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2540    Accepted Submission(s): 850

Problem Description

The
story happened long long ago. One day, Cao Cao made a special order
called "Chicken Rib" to his army. No one got his point and all became
very panic. However, Cao Cao himself felt very proud of his interesting
idea and enjoyed it.

Xiu Yang, one of the cleverest counselors of
Cao Cao, understood the command Rather than keep it to himself, he told
the point to the whole army. Cao Cao got very angry at his cleverness
and would like to punish Xiu Yang. But how can you punish someone
because he‘s clever? By looking at the chicken rib, he finally got a new
idea to punish Xiu Yang.

He told Xiu Yang that as his reward of
encrypting the special order, he could take as many gold sticks as
possible from his desk. But he could only use one stick as the
container.

Formally, we can treat the container stick as an L length segment. And the gold sticks as segments too. There were many gold sticks with different length ai and value vi.
Xiu Yang needed to put these gold segments onto the container segment.
No gold segment was allowed to be overlapped. Luckily, Xiu Yang came up
with a good idea. On the two sides of the container, he could make part
of the gold sticks outside the container as long as the center of the
gravity of each gold stick was still within the container. This could
help him get more valuable gold sticks.

As a result, Xiu Yang
took too many gold sticks which made Cao Cao much more angry. Cao Cao
killed Xiu Yang before he made himself home. So no one knows how many
gold sticks Xiu Yang made it in the container.

Can you help solve the mystery by finding out what‘s the maximum value of the gold sticks Xiu Yang could have taken?

Input

The first line of the input gives the number of test cases, T(1≤T≤100). T test cases follow. Each test case start with two integers, N(1≤N≤1000) and L(1≤L≤2000), represents the number of gold sticks and the length of the container stick. N lines follow. Each line consist of two integers, ai(1≤ai≤2000) and vi(1≤vi≤109), represents the length and the value of the ith gold stick.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum value of the gold sticks Xiu Yang could have taken.

Sample Input

4

3 7
4 1
2 1
8 1

3 7
4 2
2 1
8 4

3 5
4 1
2 2
8 9

1 1
10 3

Sample Output

Case #1: 2
Case #2: 6
Case #3: 11
Case #4: 3

Hint

In the third case, assume the container is lay on x-axis from 0 to 5. Xiu Yang could put the second gold stick center at 0 and put the third gold stick center at 5,
so none of them will drop and he can get total 2+9=11 value.

In the fourth case, Xiu Yang could just put the only gold stick center on any position of [0,1], and he can get the value of

分析:dp[i][j][k]表示决定前i个物品的取舍情况时,所用容器长度为j,

有k个物品重心放在边缘的最大价值,

状态转移方程:dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-len[i]][k]+value[i]),(j>=need[i],即max(放第个,不放第i个)),

当k>0时,还有dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-len[i]/2][k-1]+value[i]),(即max(不放第i个,第i个重心放在边缘)),

先把容器容量和每个物品的长度都乘2,避免出现小数,写的时候把三维数组优化成二维数组。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int len[1002],value[1002];
long long dp[4003][3];
int main()
{
    int T,cas=0,N,M;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&N,&M);
        M*=2;
        long long ans=0;
        for(int i=1;i<=N;i++)
        {
            scanf("%d%d",&len[i],&value[i]);
            len[i]*=2;
            ans=max(ans,(long long)value[i]);
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=N;i++)
        {
            for(int j=M;j-len[i]/2>=0;j--)
            {
                for(int k=0;k<3;k++)
                {
                    if(j>=len[i])
                        dp[j][k]=max(dp[j][k],dp[j-len[i]][k]+value[i]);
                    if(k>0)
                        dp[j][k]=max(dp[j][k],dp[j-len[i]/2][k-1]+value[i]);
                    ans=max(ans,dp[j][k]);
                }
            }
        }
        printf("Case #%d: %lld\n",++cas,ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/ACRykl/p/8660678.html

时间: 2024-10-11 11:41:40

hdu5543(Pick The Sticks) 01背包的相关文章

DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)

题目传送门 题意:长度为L的金条,将n根金棍尽可能放上去,要求重心在L上,使得价值最大,最多有两条可以长度折半的放上去. 分析:首先长度可能为奇数,先*2.然后除了两条特殊的金棍就是01背包,所以dp[now][j][k]表示当前状态,长度为j,使用了k条特殊金棍获得的最大价值,需要对内存和时间优化. /************************************************ * Author :Running_Time * Created Time :2015/10/2

2015南阳CCPC D - Pick The Sticks 背包DP.

D - Pick The Sticks Description The story happened long long ago. One day, Cao Cao made a special order called "Chicken Rib" to his army. No one got his point and all became very panic. However, Cao Cao himself felt very proud of his interesting

2015南阳CCPC D - Pick The Sticks dp

D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened long long ago. One day, Cao Cao made a special order called "Chicken Rib" to his army. No one got his point and all became very panic. However, Cao

bnu 28890 &amp;zoj 3689——Digging——————【要求物品次序的01背包】

Digging Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ID: 368964-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None Graph Theory 2-SAT Articulation

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

17-又见01背包

/*                                        又见01背包时间限制:1000 ms  |  内存限制:65535 KB难度:3 描述        有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W     的物品,求所有挑选方案中物品价值总和的最大值.    1 <= n <=100    1 <= wi <= 10^7    1 <= vi <= 100    1 <= W <= 10^

HDU - 2602 Bone Collector(01背包讲解)

题意:01背包:有N件物品和一个容量为V的背包.每种物品均只有一件.第i件物品的费用是volume[i],价值是value[i],求解将哪些物品装入背包可使价值总和最大. 分析: 1.构造二维数组:dp[i][j]---前i件物品放入一个容量为j的背包可以获得的最大价值. dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - volume[i]] + value[i]);---(a) (1)dp[i - 1][j]---不放第i件物品,因此前i件物品放入一个容量为

01背包

这里就只放自己刷的题目了,毕竟是弱弱哒 HDU2546:饭卡 1 #include <algorithm> 2 #include <cstdio> 3 4 using namespace std; 5 6 int main() 7 { 8 int n,m; 9 while (~scanf("%d", &n), n) 10 { 11 int f[2013] = {0}, menu[2013] = {0}; 12 for (int i = 1; i <

hdu 1864 01背包 最大报销额

http://acm.hdu.edu.cn/showproblem.php?pid=1864 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的选拔 最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18562    Accepted Submission(s): 5459