NYOJ311-完全背包

完全背包
时间限制:3000 ms    内存限制:65535 KB
难度:4
描述
直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入

背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背包恰好装满背包时,求出最大价值总和是多少。如果不能恰好

装满背包,输出NO

输入
第一行: N 表示有多少组测试数据(N7)。
接下来每组测试数据的第一行有两个整数M,V。 M表示物品种类的数目,V表示背包的总容量。(0M=2000,0V=50000)
接下来的M行每行有两个整数c,w分别表示每种物品的重量和价值(0c100000,0w100000)
输出
对应每组测试数据输出结果(如果能恰好装满背包,输出装满背包时背包内物品的最大价值总和。 如果不能恰好装满背包,输出NO)

样例输入
2
1 5
2 2
2 5
2 2
5 1

样例输出
NO
1

AC代码:

<p>#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int INF = -2147483647;
int w[2100],v[2100],dp[51000];
int max(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int i,j,T,n,m;
    scanf("%d",&T);
    while(T--)
    {
      scanf("%d %d",&n,&m);
      memset(dp,0,sizeof(dp));//后期全靠dp[0]==0了
      for(i=1;i<=n;i++)
      scanf("%d %d",&w[i],&v[i]);
      for(i=1;i<=m;i++)
      dp[i]=INF;
      for(i=1;i<=n;i++)
      for(j=w[i];j<=m;j++)
      dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
      if(dp[m]>=0)
      printf("%d\n",dp[m]);
      else
      printf("NO\n");
    }
    return 0;
}</p>
时间: 2024-12-03 22:02:17

NYOJ311-完全背包的相关文章

HDU 3339 In Action:最短路+背包

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3339 题目: Problem Description Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the number of nuclear weapons have soared across the globe. Nowadays,the crazy bo

UVa 624 CD (0-1背包)

624 - CD Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=565 You have a long drive by car ahead. You have a tape recorder, but unfortunately your best mus

UVa 562 Dividing coins (0-1背包&amp;amp;等价转化)

562 - Dividing coins Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=503 It's commonly known that the Dutch have invented copper-wire. Two Dutch men were

算法:zoj 3201 Tree of Tree(树形背包dp)

题意 给一棵节点带权的树,找到一个有k个节点的子树,求这个子树的最大权值 思路 树形 dp+背包. f(i, j) 表示以i为根节点的有j个节点子树的最大权值 然后对i的每个子节点做分组背包, 因为对于i的每个儿子,可以选择分配 1,2,3...j-1个节点给它 f(i, j) = max{ max{f(i, j-p) + f(v, p) | 1<=p<j} | v是i的儿子节点} ans = max{ f[i][k] | 0<=i<n && i 子树节点个数>

算法:uva 1407 Caves (树形背包dp)

题意 一棵n个节点的树,树的边有正整数权,表示两个节点之间的距离.你的任务是回答这样的询问:从跟 节点出发,走不超过x单位的距离, 最多能经过多少节点?同一个节点经过多次, 只能算一个. 思路 这题同样是多天前看的, 在今天才想出解法的. 动态规划就是这么有意思 :) 遍历n个节点, 有两种情 况, 第一种是遍历完之后不回到出发点, 第二种是要回到出发点. 两种都可能会重复经过某些边, 但是显 然还是第二种遍历的花费会更大 在这一题中, 遍历之后不需要回到出发点. f(i, j, 0): 表示遍

算法:poj 3345 Bribing FIPA (树形背包dp | 输入坑)

题意 有n个国家,你要获取m个国家的支持,获取第i个国家的支持就要给cost[i]的价钱 其中有 一些国家是老大和小弟的关系,也就是说,如果你获得了某个老大国家的支持, 那么这个国家的所有小弟 (包括小弟的小弟...递归下去)都会无偿免费支持你. 问最少的花费可以得到m个国家的支持 思路 这题还是比较好想的树形dp, 不过输入有些麻烦, 一开始以为每组样例结束都是'#',结果一直 RE,后来发现最后一组才是 '#'... 国家由于是直接给名字的,所以我用map<string, int>来映射保

算法:poj 2486 Apple Tree (树形背包dp)

题意 给一个n个节点的树,节点编号为1~n, 根节点为1, 每个节点有一个权值. 从根节点出发,走 不超过k步,问最多可以获取多少权值? 思路 因为和uva-1407 caves有点相似,所以没想很久就AC 了,但因为初始化问题WA了两次 f(i, j, 0): 表示子树i,走j次,最终不用回到i点获取的最大总权值 f(i, j, 1): 表示子树i,走j次,最终一定要回到i点获取的最大总权值 f(i, j, 1) = min{ min{ f(i, j-k, 1) + f(v, k-2, 1)

算法:poj 1947 Rebuilding Roads (树形背包dp)

题意 给一棵树,问最少删掉几条边.使得剩下的子树中有节点个数为p个的 思路 几天前就看了 这题, 但是没什么想法,之后每天都有去想一下, 直到今天, 在我对自己方法还有怀疑 的情况下,竟然AC了 .. f(i, j) 表示子树i,保留j个节点的最少删边次数, 注意,这里保留的j个节点的子树,是指根节点 为i的且有j个节点的子树.这样理解的话, 状态转移就容易想多了. 对于子树i, 如果只保留1个节 点,那么连接它所有儿子节点的边都要删掉, 所以可以初始化 f(i, 1) = 节点i的儿子个数 f

算法:poj 1155 TELE (树形背包dp)

题意 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结 构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从 转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号 的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪 些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况 下使观看转播的用户尽可能多. 思路 树形

算法:hdu 1561 The more, The Better (树形背包dp)

题目 ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每 次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克 这些城堡必须先攻克其他某一个特定的城堡.你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? 思路 简单树形背包dp,当作树形背包的第一道入门题非常合适 题目给的是森林,那么给 增加一个"根节点", 指向森林中的每个树的根节点 f(i, j)表示子树i, 取j个城堡宝藏的时候 的最大值