这是道完全背包,关键点在于如何处理每种物品,第一次放时,价值为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. POJ 3090 坐标系上的视线遮蔽问题

    Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...

  2. 【BFS+优先级队列】Rescue

    https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/I [题意] 给定一个n*m的迷宫,A的多个小伙伴R要去营救A,问需要时间最少的小 ...

  3. 静态工具类中使用注解注入service实例

    一般需要在一个工具类中使用@Autowired 注解注入一个service.但是由于工具类方法一般都写成static,所以直接注入就存在问题. 使用如下方式可以解决: /** * */ package ...

  4. django学习之- json序列化

    序列化操作 - Errordict - 自定义Encoder - django的模块可以直接序列化 第一种: from django.core import serializers # 通过这个模块对 ...

  5. 前端学习之-- DOM

    Dom == document 1:查找 1:直接查找 document.getElementById('i1') # 根据ID获取一个标签(获取单个元素) document.getElementsB ...

  6. python学习之---- paramiko 模块

    paramiko 模块 功能:提供了ssh及sftp进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. 1  基于用户名和密码的 sshclient 方式登录 ...

  7. RabbitMQ最佳实践

    在使用消息机制时,我们通常需要考虑以下几个问题: 消息不能丢失 保证消息一定能投递到目的地 保证业务处理和消息发送/消费的一致性 本文以RabbitMQ为例,讨论如何解决以上问题. 消息持久化 如果希 ...

  8. eclipse中maven插件上传项目jar包到私服

    我们知道,每一个公司都会有自己的工具包或公共包.这样的包就能够上传到公司的maven私服,就不用每一个人都去同步开发包了. 那么,怎么把本地项目打包并公布到私服呢?依照例如以下步骤就能够轻松完毕. 1 ...

  9. Excel中INDEX函数的使用

    1 函数INDEX( )有两种形式: 数组形式——INDEX(array,row_num,column_num)和 引用形式——INDEX(reference,row_num,column_num,a ...

  10. 【APUE】进程基础

    进程标识符:非负整数 ID为0的进程通常是是调度进程,常被称为交换进程.该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程 ID为1的进程是init进程,在自举过程结束时由内核调用 ...