HDU 5543 Pick The Sticks:01背包变种

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543

题意:

  给你N个金条和一张长度为L的桌子。每个金条长度为a[i],价值为w[i]。金条只能在桌子上横着摆一排,并且只要金条的重心(中心)在桌子上,就可以放。问你在桌子上能够摆的金条的最大总价值。

题解:

  首先表示状态:

    考虑到第i个金条,在这之前已经占用了j的长度,在k个端点摆了金条。即:dp[i][j][k]

  如何转移(逆推):

    对于第i个金条,有三种决策:摆在桌子中央、摆在桌子端点处、不摆。

    (1)摆在中央:dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-a[i]][k])

    (2)摆在端点:dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-a[i]/2][k-1])

    (3)不摆:  dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k])

  求dp:枚举i,j,k即可。

  注:(1)由于空间限制,dp[i][j][k]去掉第一维[i],枚举j时从大到小枚举。

    (2)由于计算金条长度的一半时会出现浮点数,所以在读入时就将所有a[i]*=2,并且L*=2。

AC Code:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX_N 1005
#define MAX_L 4005
#define MAX_K 5

using namespace std;

int n,l,t;
long long ans;
long long a[MAX_N];
long long w[MAX_N];
long long dp[MAX_L][MAX_K];

void read()
{
    ans=0;
    cin>>n>>l;
    l*=2;
    for(int i=0;i<n;i++)
    {
        cin>>a[i]>>w[i];
        a[i]*=2;
        ans=max(ans,w[i]);
    }
}

void solve()
{
    memset(dp,0,sizeof(dp));
    for(int i=0;i<n;i++)
    {
        for(int j=l;j>=a[i]/2;j--)
        {
            for(int k=0;k<3;k++)
            {
                if(j-a[i]>=0) dp[j][k]=max(dp[j][k],dp[j-a[i]][k]+w[i]);
                if(k-1>=0) dp[j][k]=max(dp[j][k],dp[j-a[i]/2][k-1]+w[i]);
                ans=max(ans,dp[j][k]);
            }
        }
    }
}

void print()
{
    cout<<ans<<endl;
}

int main()
{
    cin>>t;
    for(int cas=1;cas<=t;cas++)
    {
        cout<<"Case #"<<cas<<": ";
        read();
        solve();
        print();
    }
}
时间: 2024-08-24 02:09:58

HDU 5543 Pick The Sticks:01背包变种的相关文章

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

HDU 5543 Pick The Sticks (01背包)

题意:输入t,表示t组样例, 输入n,len,表示物品的个数和容器长度.输入n行a,v表示没个物品的长度和价值.每个物品只要能有一半放在容器上就可以(为了平衡,如果是一个物品的话不论它有多长都可以放在这个容器上),不可以重叠,求这个容器可以放最大的价值是多少. 分析:dp[i][j][k]表示前i个物品中放入长度为j的容器中有k个物品在边缘的最大价值. #include <iostream> #include <cstdio> #include <cstring> #i

hdu 5543 Pick The Sticks(动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意:给你一根长为m的长木板和一些小木棒,每一根小木棒有它的长度和价值,这些小木棒要放在长木板上并且每一根小木棒的重心要在长木板上(即可以露出一半的长),问最大价值是多少. dp[i][j][k]  表示前i个小棒放到长度为j的木板上,其中有k个小棒放在边沿部分(边沿部分的小棒需要尽量放在木板外面,所以放在边沿的木棒落在木板上的长度为l/2).然后就是简单的01背包问题了. #include

HDU 5543 Pick The Sticks

背包变形.与普通的背包问题不同的是:允许有两个物品可以花费减半. 因此加一维即可,dp[i][j][k]表示前i个物品,有j个花费减半了,总花费为k的情况下的最优解. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include&l

HDU 2639 Bone Collector II(01背包变型)

此题就是在01背包问题的基础上求所能获得的第K大的价值. 具体做法是加一维去推当前背包容量第0到K个价值,而这些价值则是由dp[j-w[ i ] ][0到k]和dp[ j ][0到k]得到的,其实就是2个数组合并之后排序,但是实际做法最好不要怎么做,因为你不知道总共有多少种,而我们最多只需要前K个大的就行了(因为可能2个数组加起来的组合数达不到K个),如果全部加起来数组开多大不清楚,所以可以选用归并排序中把左右2个有序数组合并成一个有序数组的方法来做,就是用2个变量去标记2个有序数组的头,然后比

hdu 3339 In Action (最短路径+01背包)

In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3869    Accepted Submission(s): 1237 Problem Description Since 1945, when the first nuclear bomb was exploded by the Manhattan Project t

HDU 5234 Happy birthday --- 三维01背包

HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置(i,j)有一个容量为k的背包所能获得的最大价值 决策:a[i][j]处的数是否选取 不选取: dp[i][j][k]= max(dp[i-1][j][k], dp[i][j-1][k]) 选取:首先要求k >=a[i][j],那么dp[i][j][k] = max(dp[i-1][j][k-w[i

01背包变种 第k解问题 hdu 2639

先说说普通01包的状态问题吧 普通的01背包,在状态转移的过程中为了求出最优解,一定是遍历了所有的情况 然后再求的最优解.那么对于第k最优解问题,我们只需要再加一个维度,用来记录每一个状态k优解的状态就好了. 在普通背包过程中 每次的选举的状态为dp[i-1][j],dp[i-1][j-c[i]+w[i]  为了求解最优情况 我们一般是对这两个状态取最大值 然后依次遍历 得到最大值.那么,为了得到第k大的解,我们就需要另外使用数组来对两种状态的所有值记录下来 然后选取第k大的情况 上代码 #in

hdu 2602 Bone Collector(01背包)

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 42179    Accepted Submission(s): 17543 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bon