当前位置: 代码迷 >> 综合 >> D - Pick The Sticks HDU - 5543(特殊的01背包,dp,放金条超出背包空间)
  详细解决方案

D - Pick The Sticks HDU - 5543(特殊的01背包,dp,放金条超出背包空间)

热度:50   发布时间:2024-02-10 17:59:09.0

D - Pick The Sticks HDU - 5543
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 3.

题目意思是,一个长的容器,,然后n种金条,往里面放,,容器的两端,,如果放入的金条的重心在容器里面,也就是中点在里面,,那么是成立的,所以两端可以冒出来,,所以就分为三种情况,不冒出,一边冒出,两遍冒出

#include <algorithm>
#include <cstring>
#include <iostream>
#include<cstdio>
using namespace std;
struct node
{int w;long long v;
} a[10000];
int main()
{int t;cin>>t;int casee=1;while(t--){int n,m;cin>>n>>m;m*=2;        //将容器乘以2倍,防止金条是奇数的情况无法除以二long long maxx=0;for(int i=0; i<n; i++){cin>>a[i].w>>a[i].v;a[i].w*=2;      //将金条乘以2倍,if(a[i].w>=2*m){maxx=max(maxx,a[i].v);  //找到金条的一半但是还是比容器大的,}                           //然后找到这些中的最大的价值,因为如果它大于其他}                       //一些的总和的话,直接把这条的重心放在容器的里面就oklong long dp[10000][3]; //[3]分别代表不能露出头,一边露出头,俩边露出头memset(dp,0,sizeof(dp));for(int i=0; i<n; i++)   //遍历全部金条{if(a[i].w>=2*m)  //如果这个if成立,上面已经记录了,无需再记录{continue;}for(int j=m; j>=0; j--)   //遍历容器大小{for(int k=0; k<3; k++)   //遍历三种情况{if(j-a[i].w>=0)  //如果容器能装下全部就装下,{//普通背包过程dp[j][k]=max(dp[j][k],dp[j-a[i].w][k]+a[i].v);}        //如果可以放一半,把这个一半的情况放入,if(k&&a[i].w<=2*j){//这里从k-1的情况放入,代表在k-1个露头情况下,再加一个露头dp[j][k]=max(dp[j][k],dp[j-a[i].w/2][k-1]+a[i].v);}}}}       //找三种情况最大long long ans=max(dp[m][0],dp[m][1]);ans=max(ans,dp[m][2]);    //再和最上面存的那个最大的比较printf("Case #%d: %lld\n",casee++,max(ans,maxx));}
}