简单的背包问题(入门)HDU2602 HDU2546 HDU1864
动态规划,我一直都不熟悉,因为体量不够,所以今天开始努力地学习学习。
当然背包从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的更多相关文章
- 一个简单的iBatis入门例子
一个简单的iBatis入门例子,用ORACLE和Java测试 目录结构: 1.导入iBatis和oracle驱动. 2.创建类Person.java package com.ibeats;import ...
- CJOJ 2022 【一本通】简单的背包问题(搜索)
CJOJ 2022 [一本通]简单的背包问题(搜索) Description 设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,-wn. 问能否从这n件物品中选择若干件放入 ...
- linux systemd 从简单的例子入门
linux systemd 从简单的例子入门 网上很多相关链接,一上来就给一大堆命令和讲解,让人头都大. 我们希望有一个service(服务),让它在开机启动的时候就执行. 用 root 登陆以后: ...
- 超简单!pytorch入门教程(五):训练和测试CNN
我们按照超简单!pytorch入门教程(四):准备图片数据集准备好了图片数据以后,就来训练一下识别这10类图片的cnn神经网络吧. 按照超简单!pytorch入门教程(三):构造一个小型CNN构建好一 ...
- 【动态规划】【C/C++】简单的背包问题
简单的背包问题 背包问题动态规划中非常经典的一个问题,本文只包含01背包,完全背包和多重背包.更加详尽的背包问题的讲解请参考崔添翼大神的<背包九讲> 简单的01背包 问题导入:新年到了,m ...
- Mysql数据库的简单介绍与入门
Mysql数据库的简单介绍与入门 前言 一.下载与安装 1.下载 官网下载MYSQL5.7.21版本,链接地址https://www.mysql.com/downloads/.下载流程图如下: 找到M ...
- 最简单的Github入门基础
起因是小伙伴分享给我github上的一个FQ工具,让我看实现过程.于是,就由关键字"github"搜索开始. 一言之,是个开源的SVN.和CVS.SVN类似,但是,里面有千千万万程 ...
- 前端们,gulp该用起来了,简单的demo入门——gulp系列(一)
gulp.grunt前端自动化工具,只有用过才知道多么重要. 它们问世这么久了?你真的用过吗? 写个简单的less.watch任务的demo分享———— 1.准备: 安装全局node.npm,这个教程 ...
- 一个最简单的Dubbo入门框架
Dubbo背景和简介 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 1.单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本 ...
随机推荐
- UVA 10652 Board Wrapping(凸包)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32286 [思路] 凸包 根据角度与中心点求出长方形所有点来,然后就 ...
- C++ 把输出结果写入文件/从文件中读取数据
先包含头文文件 #include<fstream> 输出到文件 ofstream fout; //声明一个输出流对象 fout.open("output.txt"); ...
- debmirror镜像站
如何建立一个Debian镜像网站呢?在Debian的官方网站已经有专门的介绍: http://www.debian.org/mirror/ftpmirror 这是基于rsync软件的方法,网页也提供了 ...
- PyDev+eclipse的编码问题
1.在代码的开始声明编码为utf-8
- GUI(图形用户界面)
一.GUI(图形用户界面) GUI Graphical User Interface(图形用户接口) 用图形的方式,来显示计算机操作的界面,这样更方便更直观 CLI Command line User ...
- NOIP-2003 加分二叉树
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- centos7 搭建 docker 环境
1. 安装centos7 http://isoredirect.centos.org/centos/7/isos/x86_64/ 下载 everything 版本,最小化版本可能缺失很多东西 我是在 ...
- 非堵塞socket实现android手机与PC的文件传输
项目须要是通过WIFI建立手机和PC的通信,然后自己定义一个简单的协议对要传输的文件进行校验,传输的文件是2张3M的图片,要求考虑网络中断情况处理. 我这里採用的是非堵塞socket来实现的,之前查过 ...
- git 命令归纳
git 新手一枚,随用随更新 git clone git@example.com:project-name.git 克隆 git branch [-a -r] 查看分支[所有 远端] git pull ...
- [转]flume-ng+Kafka+Storm+HDFS 实时系统搭建
http://blog.csdn.net/weijonathan/article/details/18301321 一直以来都想接触Storm实时计算这块的东西,最近在群里看到上海一哥们罗宝写的Flu ...