UESTC 1218 Pick The Sticks (dp )

题目: 一根长为m的长木板和一些小木棒,每一根小木棒有它的长度和价值,这些小木棒要放在长木板上并且每一根小木棒的重心要在长木板上(可以露出一半的长),最大价值是多少。

让人联想到01背包,但是又有些许的不同。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=4e3+10;
typedef long long LL;
LL dp[N][5];    // 0,1,2分别表示露在外面的木棍数量
LL a[1010],v[1010];
int main()
{
    //freopen("cin.txt","r",stdin);
    LL n,t=0,m,len;
    cin>>n;
    while(n--){
        scanf("%lld%lld",&m,&len);
        len=len*2;
        LL ans=0;
        for(int i=0;i<m;i++){
            scanf("%lld%lld",&a[i],&v[i]);
            a[i]=a[i]*2;
            ans=max(ans,v[i]);
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<m;i++){
            for(int j=len;j>=a[i]/2;j--){
                dp[j][1]=max(dp[j-a[i]/2][0]+v[i],dp[j][1]); // outside
                dp[j][2]=max(dp[j-a[i]/2][1]+v[i],dp[j][2]);
                // 不放就仍然使用原值
                if(j>=a[i]){
                    dp[j][0]=max(dp[j-a[i]][0]+v[i],dp[j][0]);  //inside
                    dp[j][1]=max(dp[j-a[i]][1]+v[i],dp[j][1]);
                    dp[j][2]=max(dp[j-a[i]][2]+v[i],dp[j][2]);
                }
            }
        }
        for(int i=0;i<3;i++){
              ans=max(ans,dp[len][i]);
        }
        printf("Case #%lld: %lld\n",++t,ans);
    }
    return 0;
}

注意:  那个双重循环里的第二层循环如果写成 for(int j=a[i]/2;j<=len;j++) //这种遍历会造成数据污染(滚动数组),除非再开一维。另外,因为输出格式不对,%lld--写成-->%I64d 居然出现了 (Restricted Function on test 1)瞬间惊呆了我。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值