动态规划,我一直都不熟悉,因为体量不够,所以今天开始努力地学习学习。

当然背包从01开始,先选择了一个简单的经典的背包HDU2602。

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …

The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the
maximum of the total value the bone collector can get ?

The first line contain a integer T , the number of cases.

Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third
line contain N integers representing the volume of each bone.

One integer per line representing the maximum of the total value (this number will be less than 231).

Input

1
5 10
1 2 3 4 5
5 4 3 2 1

Output

14

C++代码

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-08
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/ #include <iostream>
#include <cstring>
int max(int a,int b){
return a>b?a:b; }
using namespace std;
int dp[1003];
int v[1003];
int w[1003];
int main(){
int cases,i,j,val,n;
cin>>cases;
while(cases--){
memset(dp,0,sizeof(dp));
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
cin>>n>>val;
for(i=1;i<=n;i++){
cin>>w[i];
}
for(i=1;i<=n;i++){
cin>>v[i];
}
for(i=1;i<=n;i++)
for(j=val;j>=v[i];j--)
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
cout<<dp[val]<<endl; } return 0;
}

后来特意选了一道HDU的简单背包问题。HDU的2546。

题目很简单:

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。

某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

多组数据。对于每组数据:

第一行为正整数n,表示菜的数量。n<=1000。

第二行包括n个正整数,表示每种菜的价格。价格不超过50。

第三行包括一个正整数m,表示卡上的余额。m<=1000。



n=0表示数据结束。

对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。

其实这道题在01背包上多了一个弯,就是卡余额大于等于5可以购买任何东西。只要留下5元买最贵的东西,剩下的就是一个背包问题了。

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-08
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/
//* #include <iostream>
#include <cstring> using namespace std;
int min(int a,int b){
return a>b?b:a;
}
int main() {
int n,i,j,V;
int c[1002];
int f[1002]; while(cin>>n&&n){
int max=0,mi=0;
for(i=1;i<=n;i++){
cin>>c[i];
//cout<<c[i];
if(c[i]>max){
max=c[i];
mi=i;
}
}
cin>>V;
if(V<5){
cout<<V<<endl;
}else{ for(j=0;j<=V;j++)
f[j]=V;
V-=5;
for(i=1;i<=n;i++)
if(i!=mi)
for(j=V;j>=c[i];j--){
f[j]=min(f[j],f[j-c[i] ]-c[i]);
} cout<<f[V]-c[mi]<<endl; }
} return 0; }

对于HDU1864这题目,则是明显的01背包,但是其中要做一些小小的处理。

我的方法很一般,而且效率也不怎么高,就算是很传统吧。如果用C语言写的话会略去一些没必要的字符串处理过程。

因为题目是两位小数的,所以我很暴力地全部*100,空间浪费了很多,但是500000的空间能过。

现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。

测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(<=30)是发票张数。随后是 N 行输入,每行的格式为:

m Type_1:price_1 Type_2:price_2 ... Type_m:price_m

其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。

代码:

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-08
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/
//* #include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iomanip> using namespace std;
int max(int a,int b){
return a>b?a:b;
}
int f[5000000];
int main() {
float money;
int n,m,i,j;
string tmp;
float c[32];
//float f[32]; int ci[32];
int moneyi;
// freopen("input.txt","r",stdin);
while(cin>>money>>n&&n){
memset(f,0,sizeof(f));
memset(c,0.0f,sizeof(c));
for(i=1;i<=n;i++){
cin>>m;
int flag=1;
float A,B,C;
A=B=C=0.0f;
while(m--){
cin>>tmp; float a; if(tmp[0]=='A'){
tmp.erase(0,1);
tmp.erase(0,1);
a=atof(tmp.c_str());
A+=a; }else if(tmp[0]=='C'){
tmp.erase(0,1);
tmp.erase(0,1);
a=atof(tmp.c_str());
C+=a; }else if(tmp[0]=='B'){
tmp.erase(0,1);
tmp.erase(0,1);
a=atof(tmp.c_str());
B+=a; }else{
flag=0; }
}
if(flag&&A+B+C<=1000.0f&&A<=600.0F&&B<=600.0F&&C<=600.0f){
c[i]=A+B+C; }else{
c[i]=0;
}
//cout
// cout<<c[i]<<endl;
}
for(i=1;i<=n;i++){
//cout<<100*c[i];
ci[i]=(int)(100*c[i]);
// cout<<"ci[i]"<<ci[i]<<endl; }
moneyi=(int)(money*100);
//cout<<"m="<<moneyi<<endl;
for(i=1;i<=n;i++)
for(j=moneyi;j>=ci[i];j--){
f[j]=max(f[j],f[j-ci[i]]+ci[i]); }
double xs=f[moneyi]/100.0;
cout<<setprecision(2) <<std::fixed<<xs<<endl; }
// fclose(stdin); //关闭文件 return 0; }

C代码:

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : GCC 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-08
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/ #include <stdio.h>
#include <string.h> int main(){ double money,A,B,C,tmp;
int n,m,i,j,flag;
char c;
double dp[32];
double w[32]; while(scanf("%lf%d",&money,&n)!=EOF&&n){ memset(w,0,sizeof(w));
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){ scanf("%d",&m);
A=B=C=0;
flag=1;
for(j=1;j<=m;j++){ scanf(" %c:%lf",&c,&tmp); if(c=='A'){
A+=tmp;
}else if(c=='B'){
B+=tmp;
}else if(c=='C'){
C+=tmp; }else{
flag=0;
} }
if(flag&&A<=600.0&&B<=600.0&&C<=600.0&&A+B+C<=1000.0){
w[i]=A+B+C;
}else{
w[i]=0.0;
} } for(i=1;i<=n;i++)
for(j=n;j>=1;j--)
if(money-w[j]>=dp[j-1]||j==1)
dp[j]=(dp[j]>dp[j-1]+w[i])?dp[j]:dp[j-1]+w[i]; double res=0;
for(i=1;i<=n;i++){
if(res<=dp[i]) res=dp[i]; }
printf("%.2lf\n",res); } return 0;
}

简单的背包问题(入门)HDU2602 HDU2546 HDU1864的更多相关文章

  1. 一个简单的iBatis入门例子

    一个简单的iBatis入门例子,用ORACLE和Java测试 目录结构: 1.导入iBatis和oracle驱动. 2.创建类Person.java package com.ibeats;import ...

  2. CJOJ 2022 【一本通】简单的背包问题(搜索)

    CJOJ 2022 [一本通]简单的背包问题(搜索) Description 设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,-wn. 问能否从这n件物品中选择若干件放入 ...

  3. linux systemd 从简单的例子入门

    linux systemd 从简单的例子入门 网上很多相关链接,一上来就给一大堆命令和讲解,让人头都大. 我们希望有一个service(服务),让它在开机启动的时候就执行. 用 root 登陆以后: ...

  4. 超简单!pytorch入门教程(五):训练和测试CNN

    我们按照超简单!pytorch入门教程(四):准备图片数据集准备好了图片数据以后,就来训练一下识别这10类图片的cnn神经网络吧. 按照超简单!pytorch入门教程(三):构造一个小型CNN构建好一 ...

  5. 【动态规划】【C/C++】简单的背包问题

    简单的背包问题 背包问题动态规划中非常经典的一个问题,本文只包含01背包,完全背包和多重背包.更加详尽的背包问题的讲解请参考崔添翼大神的<背包九讲> 简单的01背包 问题导入:新年到了,m ...

  6. Mysql数据库的简单介绍与入门

    Mysql数据库的简单介绍与入门 前言 一.下载与安装 1.下载 官网下载MYSQL5.7.21版本,链接地址https://www.mysql.com/downloads/.下载流程图如下: 找到M ...

  7. 最简单的Github入门基础

    起因是小伙伴分享给我github上的一个FQ工具,让我看实现过程.于是,就由关键字"github"搜索开始. 一言之,是个开源的SVN.和CVS.SVN类似,但是,里面有千千万万程 ...

  8. 前端们,gulp该用起来了,简单的demo入门——gulp系列(一)

    gulp.grunt前端自动化工具,只有用过才知道多么重要. 它们问世这么久了?你真的用过吗? 写个简单的less.watch任务的demo分享———— 1.准备: 安装全局node.npm,这个教程 ...

  9. 一个最简单的Dubbo入门框架

    Dubbo背景和简介 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 1.单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本 ...

随机推荐

  1. 【转】Flask快速入门

    迫不及待要开始了吗?本页提供了一个很好的 Flask 介绍,并假定你已经安装好了 Flask.如果没有,请跳转到 安装 章节. 一个最小的应用 一个最小的 Flask 应用看起来会是这样: from ...

  2. oc学习之路----多级指针的使用和内存分析

    ---恢复内容开始--- 精髓:要熟悉指针的使用,首先要熟悉指针的各种状态存得是什么数据.(以一级指针 int *p1 二级指针:int **p2 三级指针:int ***p3为例) 一级指针:*p1 ...

  3. centos7 搭建 docker 环境

    1. 安装centos7  http://isoredirect.centos.org/centos/7/isos/x86_64/ 下载 everything 版本,最小化版本可能缺失很多东西 我是在 ...

  4. Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5

    Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of ...

  5. git 命令归纳

    git 新手一枚,随用随更新 git clone git@example.com:project-name.git 克隆 git branch [-a -r] 查看分支[所有 远端] git pull ...

  6. There is an error while getting planid. No Free partitions available

    问题概述 Oracle Advanced Supply Chain Planning最初的设置职责的时候有点问题,不知是不是要打什么补丁或其它配置什么东东,, 这个提示,,但我查到的分区是还有可用分区 ...

  7. JSPatch 成长之路

    在这次 GMTC 大会上,我见到了 JSPatch 的作者 bang.在这之前我就和他在网上认识并聊过很多次,bang 也在这个公众号上投稿发表了多篇关于 JSPatch 的文章,包括:JSPatch ...

  8. android开发必备日志打印工具类

    今天给大家献上一款好用的日志打印工具.大家在平时的开发中用的最多的可能就是Log.i("",""),Log.e("","" ...

  9. JavaScript 应用开发 #5:为完成的任务添加样式

    判断一下任务的状态,如果是完成的任务,可以在任务项目的上面,添加一个额外的 css 类,在这个 css 类里,可以去定义完成的任务的样式.比如,把文字的颜色变成浅友色,并且在文字上面添加一条删除线.这 ...

  10. Ubuntu 13.10 Rhythmbox 播放器不能播放MP3。安装插件

    Ctrl+Alt+T > sudo apt-get install ubuntu-restricted-extras 因为版权和专利的问题,MP3等一些non-free的格式文件支持没有出现在免 ...