zoukankan      html  css  js  c++  java
  • [HDOJ5543]Pick The Sticks(DP,01背包)

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

    题意:往长为L的线段上覆盖线段,要求:要么这些线段都在L的线段上,要么有不超过自身长度一半的部分在线段外面,最多有两条这样的线段(在两头)。

    dp(i,j,k)表示前i个线段覆盖在长度为j的线段上,期中有k个线段不完全在这个线段上的最大价值。考虑线段长度的奇偶问题,所以事先把L和其他线段长度乘2,以便操作。所以枚举所有线段,一般情况,就是01背包的问题,dp(i,j,k)=max(dp(i,j,k), dp(i-1,j-w(i),k)+v(i))。当枚举到k不是0的时候,还需要更新两端放的情况:dp(i,j,k)=max(dp(i,j,k),dp(i-1,j-w(i)/2,k-1)+v(i))。直接取w(i)/2是没有关系的,因为我们在这里希望可以贪心地尽可能地少占用当前L上的长度。

    还有一个trick:L=1的时候这么搞。这时L当成一个支点,只能放一个。所以要提前处理所有线段的最大价值。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 const int maxn = 5010;
     6 int w[maxn], v[maxn];
     7 int n, L;
     8 LL dp[maxn][3];
     9 LL ret;
    10 
    11 int main() {
    12   freopen("in", "r", stdin);
    13   int T, _ = 1;
    14   scanf("%d", &T);
    15   while(T--) {
    16     scanf("%d %d", &n, &L);
    17     memset(dp, 0, sizeof(dp));
    18     ret = 0; L <<= 1;
    19     for(int i = 1; i <= n; i++) {
    20       scanf("%d %d", &w[i], &v[i]);
    21       w[i] <<= 1;
    22       ret = max(ret, (LL)v[i]);
    23     }
    24     for(int i = 1; i <= n; i++) {
    25       for(int j = L; j >= w[i]/2; j--) {
    26         for(int k = 0; k <= 2; k++) {
    27           if(j >= w[i]) dp[j][k] = max(dp[j][k], dp[j-w[i]][k]+v[i]);
    28           if(k) dp[j][k] = max(dp[j][k], dp[j-w[i]/2][k-1]+v[i]);
    29            ret = max(ret, dp[j][k]);
    30         }
    31       }
    32     }
    33     printf("Case #%d: %lld
    ", _++, ret);
    34   }
    35   return 0;
    36 }
  • 相关阅读:
    基于select的IO多路复用并发模型
    (p ython +tcp+tcp)文件传输
    udp协议与进程结合(群聊)
    python递归拷贝目录和线程拷贝目录
    利用线程对文件进行分割
    tcp与线程结合
    tcp 文件传输
    mysql数据库 (使用) 测试题
    json写入文件
    ArcEngine——获取要素几何(非游标方式)
  • 原文地址:https://www.cnblogs.com/kirai/p/5955455.html
Copyright © 2011-2022 走看看