这是道完全背包,关键点在于如何处理每种物品,第一次放时,价值为A+B,以后放时,价值为A。

所以有三种决策,对于第i种物品,要么不放,要么是作为第一个放,要么是第二个以后放。
作为第一个放时,需要用到上一行的状态,所以需要增加一个状态表示上一行的状态。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 300000
#define LL long long
using namespace std;
int V[maxn],A[maxn],B[maxn];
int d[maxn]; //d[j]代表容量为j的背包,处理到第i种物品时的最大值
int p[maxn]; //p[j]代表容量为j的背包,处理到上一行物品的最大值
int M,N;
void init()
{
memset(d,,sizeof(d));
memset(p,,sizeof(p));
}
void solve()
{
for(int i=;i<=N;i++)
{
for(int j=V[i];j<=M;j++)
{
d[j]=max(d[j-V[i]]+A[i],d[j]); //要么不是第一个放
d[j]=max(p[j-V[i]]+A[i]+B[i],d[j]); //要么是第一个放
}
for(int j=;j<=M;j++)
{
p[j]=d[j];
}
}
int ans=;
for(int j=;j<=M;j++)
ans=max(ans,d[j]);
printf("%d\n",ans);
}
int main()
{
//freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&M,&N);
for(int i=;i<=N;i++)
{
scanf("%d%d%d",&V[i],&A[i],&B[i]);
}
solve();
}
return ;
}
第一次做时陷入了一个误区,就是说d[j]=max(d[j-V[i]]+W[i],d[j]);,我想的是用一个数组来记录容量为j的背包能够取得的最大价值的隐含的序列是否放过i种物品,
如果是第一次放,那么W[i]=A+B,如果是第二次放,那么W[i]=A;
可是没有考虑到对于第i种物品,每种容量都有放0,1,一个以上的权利,

但是这样考虑的话,写的时候,就写成了下面这个样子,如果j-V[i]放过的话,那么j容量就只能不放,或者放2个以上。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 300000
#define LL long long
using namespace std;
int V[maxn],A[maxn],B[maxn];
int d[maxn];
int M,N;
int visit[maxn];
void init()
{
memset(d,,sizeof(d));
}
void solve()
{
for(int i=;i<=N;i++)
{
memset(visit,,sizeof(visit));
int t=;
for(int j=V[i];j<=M;j++)
{
if( visit[j-V[i]]==) //如果之前没有放过
{
if(d[j-V[i]]+A[i]+B[i]>=d[j]) //加上A+B
{
d[j]=d[j-V[i]]+A[i]+B[i];
visit[j]=;
}
}
else //如果放过,加上A
{
// if(j==M)
// printf("d[j]: %d d[j-V[i]] %d V[i] %d\n",d[j],d[j-V[i]],V[i]);
if(d[j-V[i]]+A[i]>=d[j])
{
d[j]=d[j-V[i]]+A[i];
visit[j]=;
}
}
// d[j]=max(d[j-V[i]]+A[i]+B[i],d[j]);
printf("%d ",d[j]);
t++;
if(t%==)
printf("\n");
}
printf("\n\n");
}
printf("%d\n",d[M-]);
}
int main()
{
freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&M,&N);
for(int i=;i<=N;i++)
{
scanf("%d%d%d",&V[i],&A[i],&B[i]);
}
solve();
}
return ;
}

hdu5410(完全背包变形)的更多相关文章

  1. FZU 2214 Knapsack problem 01背包变形

    题目链接:Knapsack problem 大意:给出T组测试数据,每组给出n个物品和最大容量w.然后依次给出n个物品的价值和体积. 问,最多能盛的物品价值和是多少? 思路:01背包变形,因为w太大, ...

  2. Codeforces Round #214 (Div. 2) C. Dima and Salad (背包变形)

    C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  3. codeforce Gym 101102A Coins (01背包变形)

    01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstri ...

  4. HDU 2639 Bone Collector II(01背包变形【第K大最优解】)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. P1282 多米诺骨牌 (背包变形问题)

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  6. 【01背包变形】Robberies HDU 2955

    http://acm.hdu.edu.cn/showproblem.php?pid=2955 [题意] 有一个强盗要去几个银行偷盗,他既想多抢点钱,又想尽量不被抓到.已知各个银行 的金钱数和被抓的概率 ...

  7. J-流浪西邮之寻找火石碎片 【经典背包变形】

    题目来源:2019 ACM ICPC Xi'an University of Posts & Telecommunications School Contest 链接:https://www. ...

  8. CF#214 C. Dima and Salad 01背包变形

    C. Dima and Salad 题意 有n种水果,第i个水果有一个美味度ai和能量值bi,现在要选择部分水果做沙拉,假如此时选择了m个水果,要保证\(\frac{\sum_{i=1}^ma_i}{ ...

  9. Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)

    传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...

随机推荐

  1. 在后台根据单据标识构建单据的DynamicObject,然后调用BOS的保存服务保存单据。

    var bussnessInfo = Kingdee.BOS.ServiceHelper.MetaDataServiceHelper.GetFormMetaData(this.Context, &qu ...

  2. 洛谷 P 1018 乘积最大 ==Codevs

    题目描述 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得 ...

  3. Linux下出现launch failed.Binary not found的解决方案

    Linux下出现launch failed.Binary not found的解决方案: Project->Properties->C/C++Build->Settings-> ...

  4. 安装mysql时出现应用程序无法正常启动(0xc000007b)、初始化失败以及密码忘记怎样重置?

    https://blog.csdn.net/zztingfeng/article/details/80155624

  5. hihocoder 1165 : 益智游戏

    时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 幽香今天心情不错,正在和花田里的虫子玩一个益智游戏.这个游戏是这样的,对于一个数组A,幽香从A中选择一个数a,虫子从A中选 ...

  6. Office WORD如何取消开始工作右侧栏

    工具-选项-视图,取消勾选"启动任务窗格"  

  7. C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用

    序列性容器::(vector和list和deque)   erase迭代器不仅使所有指向被删元素的迭代器失效,而且使被   删元素之后的所有迭代器失效,所以不能使用erase(iter++)的方 式, ...

  8. awk基本使用方法简单介绍

    之前说过sed, 今天来说awk, 它也是一个文本处理器. 是linux下的一个命令, 比sed更强大. 搞linux开发, 尤其是后台开发, 这个命令差点儿必需要用到. awk这三个字母分别代表其三 ...

  9. LeetCode 168 Excel Sheet Column Title(Excel的列向表标题)

    翻译 给定一个正整数,返回它作为出如今Excel表中的正确列向标题. 比如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 - ...

  10. wpf 导出Excel Wpf Button 样式 wpf简单进度条 List泛型集合对象排序 C#集合

    wpf 导出Excel   1 private void Button_Click_1(object sender, RoutedEventArgs e) 2 { 3 4 ExportDataGrid ...