• HDOJ5543 Pick The Sticks


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

    题目大意:有n个金条,每个金条有长度和价值,给一个长度为L的容器,当金条在容器两端的时候,只要重心在容器内也可以放下,问最多能获得的价值。

    思路:01背包,但是重心怎么处理,最好的肯定是边界情况也就是刚好金条刚好能伸出一半,或者直接只取一根金条然后放在容器里面。

    多开一位 dp[i][j][k]代表当前选第i个背包容量为j有k个超出边缘的金条时所能获得的最大价值

    状态转移方程 dp[i][j][2]=max(dp[i-1][j-w[i]][2]+v[i],dp[i-1][j-w[i]/2][1]+v[i],dp[i][j][2])

          dp[i][j][1]=max(dp[i-1][j-w[i]][1]+v[i],dp[i-1][j-w[i]/2][0]+v[i],dp[i][j][1])

          dp[i][j][0]=max(dp[i-1][j-w[i]][0]+v[i],dp[i][j][0])

    如果没有第一维i的话,那么j和k都要从大到小搞,很明显dp[j][1]是会影响到dp[j][2]的

    处理整除的情况很简单,容器和金条长度都*2就好了,这样就能保证一定整除

    最后不要忘了放一个的情况要特判一下

     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <string.h>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=4010;
     7 long long dp[maxn][3];
     8 long long  v[maxn],w[maxn];
     9 void init(){
    10     memset(dp,0,sizeof(dp));
    11 }
    12 void beibao(int pos,int V) {
    13     for(int i=V;i>=w[pos]/2;i--) {
    14         dp[i][2]=max(dp[i-w[pos]/2][1]+v[pos],dp[i][2]);
    15         if(i>=w[pos])
    16         dp[i][2]=max(dp[i-w[pos]][2]+v[pos],dp[i][2]);
    17     }
    18 
    19     for(int i=V;i>=w[pos]/2;i--){
    20         dp[i][1]=max(dp[i-w[pos]/2][0]+v[pos],dp[i][1]);
    21         if(i>=w[pos])
    22         dp[i][1]=max(dp[i-w[pos]][1]+v[pos],dp[i][1]);
    23     }
    24     for(int i=V;i>=w[pos];i--) 
    25         dp[i][0]=max(dp[i-w[pos]][0]+v[pos],dp[i][0]);    
    26 }
    27 void solve(int T) {
    28     init();
    29     
    30     int n,l;
    31     scanf("%d %d",&n,&l);
    32     l<<=1;
    33     long long ans=0;
    34     for(int i=1;i<=n;i++) {
    35         scanf("%lld %lld",&w[i],&v[i]);
    36         w[i]<<=1;
    37         ans=max(ans,v[i]);
    38     }
    39     for(int i=1;i<=n;i++) {
    40         beibao(i,l);
    41     }
    42     ans=max(ans,max(dp[l][0],max(dp[l][1],dp[l][2])));
    43     printf("Case #%d: %lld
    ",T,ans);
    44 }
    45 int main() {
    46     int T;
    47     scanf("%d",&T);
    48     for(int i=1;i<=T;i++) solve(i);
    49 }
  • 相关阅读:
    Scratch编程:打猎(十)
    Scratch编程:漂亮的时钟(九)
    剑指offer总结一:字符、数字重复问题
    剑指offer:数值的整数次方
    剑指offer:二进制中1的个数
    InnoDB存储引擎与MyIsam存储引擎的区别
    数据库查询慢的原因
    剑指offer:矩形覆盖
    剑指offer:跳台阶问题
    redis键的过期和内存淘汰策略
  • 原文地址:https://www.cnblogs.com/as3asddd/p/6075798.html
Copyright © 2020-2023  润新知