PAT甲题题解-1068. Find More Coins (30)-dp,01背包
一开始没多想,虽然注意到数据N<=10^4的范围,想PAT的应该不会超时吧,就理所当然地用dfs做了,结果最后一组真的超时了。
剪枝啥的还是过不了,就意识到肯定不是用dfs做了。
直到看到别人说用01背包的思路,果真好久没做题了智力水平下降,且原本dp就是我的弱项,压根就没把这题往dp上去想额。。。
(http://www.liuchuo.net/archives/2323)
题意:从n个硬皮中选取方案,使得总和价值正好为m,如果有多种,方案为排列最小的那个。
可以把硬币看成w=v(即容量=价值)的物品,现在要选取这些物品放入到容量为m的背包中,求能装的最大价值。
如果最大价值恰好等于容量m,那么方案则是可行的,否则输出No Solution。
由于要输出排列最小的方案,所以先将硬币按价值从大到小排列,相当于我先装大的,再装小的。
接着用01背包的方法求dp[j]。
chosen[i][j]数组表示背包里容量为j的时候,是否含有第i个物品,用于最后序列的输出。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=+;
const int maxv=;
int coins[maxn];
int dp[maxv]; //dp[v]表示:总和加起来=v的序列中最后一个值最小为多少。
int chosen[maxn][maxv];
int ans[maxn];
int cnt=; bool cmp(int a,int b){
return a>b;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=;i<n;i++){
scanf("%d",&coins[i]);
}
sort(coins,coins+n,cmp); dp[]=;
for(int i=;i<n;i++){
for(int j=m;j>=coins[i];j--){
if(dp[j]<=dp[j-coins[i]]+coins[i]){
dp[j]=dp[j-coins[i]]+coins[i];
//printf("i:%d j:%d dp:%d chosen:%d\n",i,j,dp[j],coins[i]);
chosen[i][j]=;
}
}
}
if(dp[m]!=m){
printf("No Solution");
}
else{
int v=m,idx=n-;
while(v){
if(chosen[idx][v]){
ans[cnt++]=coins[idx];
v-=coins[idx];
}
idx--;
}
printf("%d",ans[]);
for(int i=;i<cnt;i++)
printf(" %d",ans[i]);
}
return ;
}
PS:想了解背包问题的,有个《背包九讲》,网上可以搜搜看看,挺好的
PAT甲题题解-1068. Find More Coins (30)-dp,01背包的更多相关文章
- PAT甲题题解-1095. Cars on Campus(30)-(map+树状数组,或者模拟)
题意:给出n个车辆进出校园的记录,以及k个时间点,让你回答每个时间点校园内的车辆数,最后输出在校园内停留的总时间最长的车牌号和停留时间,如果不止一个,车牌号按字典序输出. 几个注意点: 1.如果一个车 ...
- PAT甲题题解-1014. Waiting in Line (30)-模拟,优先级队列
题意:n个窗口,每个窗口可以排m人.有k为顾客需要办理业务,给出了每个客户的办理业务时间.银行在8点开始服务,如果窗口都排满了,客户就得在黄线外等候.如果有一个窗口用户服务结束,黄线外的客户就进来一个 ...
- PAT甲题题解-1076. Forwards on Weibo (30)-BFS
题目大意:给出每个用户id关注的人,和转发最多的层数L,求一个id发了条微博最多会有多少个人转发,每个人只考虑转发一次.用BFS,同时每个节点要记录下所在的层数,由于只能转发一次,所以每个节点要用vi ...
- PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)
(先说一句,题目还不错,很值得动手思考并且去实现.) 题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可. 已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在 ...
- PAT甲题题解-1048. Find Coins (25)-水
给n,m以及n个硬币 问,是否存在两个硬币面值v1+v2=m 因为面值不会超过500,所以实际上最多500个不同的硬币而已 #include <iostream> #include < ...
- PAT甲题题解-1008. Elevator (20)-大么个大水题,这也太小瞧我们做题者的智商了
如题... #include <iostream> #include <cstdio> #include <algorithm> #include <cstr ...
- PAT甲题题解-1010. Radix (25)-二分搜索
题意:给出n1和n2,以及其中一个数的进制,问另一个数是多少进制的情况下,才会是两个数相等.不存在的话,则输出Impossible 这题思路很简单,但是要考虑的比较多,在简单题里面算是比较好的. 有两 ...
- PAT甲题题解-1011. World Cup Betting (20)-误导人的水题。。。
题目不严谨啊啊啊啊式子算出来结果是37.975样例输出的是37.98我以为是四舍五入的啊啊啊,所以最后输出的是sum+0.005结果告诉我全部错误啊结果直接保留两位小数就可以了啊啊啊啊 水题也不要这么 ...
- PAT甲题题解-1012. The Best Rank (25)-排序水题
排序,水题因为最后如果一个学生最好的排名有一样的,输出的课程有个优先级A>C>M>E那么按这个优先级顺序进行排序每次排序前先求当前课程的排名然后再与目前最好的排名比较.更新 至于查询 ...
随机推荐
- 使用TuShare下载历史逐笔成交数据并生成1分钟线
使用如下代码从TuShare下载沪深300每只股票的历史成交记录并按股票.日期保存到本地.主要是为了以后查询方便快速. #-*- coding: utf-8 -*- import numpy as n ...
- Vue入门1
欢迎转载,转载请注明出处. 前言 学习本系列Vue知识,需要结合本系列的一些demo.你可以查看我的 Github 或者直接下载 ZIP包 . 建议学习本系列之前已经会一个其他的前端框架,了解计算属性 ...
- <数据结构与算法分析>读书笔记--实现泛型构件pre-Java5
面向对象的一个重要目标是对代码重用的支持.支持这个目标的一个重要的机制就是泛型机制:如果除去对象的基本类型外,实现的方法是相同的,那么我们就可以用泛型实现来描述这种基本的功能. 1.使用Object表 ...
- WorldWind源码剖析系列:代理助手类ProxyHelper
代理助手类ProxyHelper通过平台调用的互操作技术封送了若干Win32结构体和函数.该类类图如下. 提供的主要处理方法基本上都是静态函数,简要描述如下: 内嵌类型WINHTTP_AUTOPROX ...
- Linux安装配置apache
Linux安装配置apache 1.获取软件: http://httpd.apache.org/ httpd-2.2.21.tar.gz 2.安装步骤: 解压源文件: 1 tar zvxf ht ...
- day33
今日内容: 1.关于UDP传输的模拟实现 2.使用socketserver模块实现TCP传输的并发操作 3.进程理论的介绍 1.关于UDP传输的模拟实现 模拟UDP传输与之前的模拟TCP传输大致相同 ...
- php实现远程网络文件下载到服务器指定目录(方法二)
<?php // maximum execution time in seconds set_time_limit (24 * 60 * 60); //if (!isset($_POST['su ...
- [SDOI2012]任务安排 BZOJ2726 斜率优化+二分查找
网上的题解...状态就没有一个和我一样的...这让我有些无从下手... 分析: 我们考虑,正常的斜率优化满足x(i)单调递增,k(i)单调递增,那么我们就可以只用维护一个单调队列满足对于当前的x(i) ...
- git reset之后找回本地未提交的代码
头脑发热使用了git reset命令回退到了之前的一个版本,结果把本地没有提交的代码给覆盖掉了..... 作为一个bug员自然是想恢复,毕竟重新写还得再测一遍,本着能懒一点是一点的原则,开始了恢复代码 ...
- 20155330 《网络对抗》 Exp9 web安全基础实践
20155330 <网络对抗> Exp9 web安全基础实践 实验问题回答 SQL注入攻击原理,如何防御 原理:SQL注入攻击值得是通过构建特殊的输入作为参数传入web应用程序,而这些输入 ...