NYOJ 654 喜欢玩warcraft的ltl (01背包常数优化)

【题目链接】:click here~~

一个常数优化

前面的伪代码中有 for v=V..1,可以将这个循环的下限进行改进。

由于只需要最后f[v]的值,倒推前一个物品,其实只要知道f[v-w[n]]即可。以此类推,对以第j个背包,其实只需要知道到f[v-sum{w[j..n]}]即可,即代码中的

for i=1..N
    for v=V..0

可以改成

for i=1..n
    bound=max{V-sum{w[i..n]},c[i]}
    for v=V..bound

这对于V比较大时是有用的。

代码:

/*
* Problem: NYOJ No.654
* Running time: 412MS
* Complier: C++
* Author: ACM_herongwei
* Create Time: 9:24 2015/9/9 星期三
* zeroonebags 的常数优化
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#define CLR(c,v) (memset(c,v,sizeof(c)))
using namespace std;

template <typename _T>
inline _T Max(_T a,_T b){
	return (a>b)?(a):(b);
}
template <typename _T>
inline _T Max(_T a,_T b,_T c){
	return (a>Max(b,c))?(a):(Max(b,c));
}
const int COST =  1e6 + 10;
const int M    =  1e4 + 10;

int dp[COST];
int value[M];
int volume[M];

int main(){
	int Ncase;
	scanf("%d",&Ncase) ;
	while(Ncase--){
		CLR(dp,0);
		int max_cost, n_bags;
		scanf("%d%d",&n_bags, &max_cost);
		for (int i = 0 ; i < n_bags ; ++i){ // max:1000
			scanf("%d%d",&volume[i],&value[i]);
		}
		for (int i = 0 ; i < n_bags ; ++i){ // max:1000
			int sum = 0;
			for(int j = i ; j < n_bags ; ++j){
				sum += volume[j];
			}
			int bound = Max(max_cost-sum , volume[i]);
			for(int j = max_cost ; j >= bound ; j--){ // max:100 0000
				if( dp[j] < dp[j-volume[i]] + value[i]){
					dp[j] = dp[j-volume[i]] + value[i];
				}
			}
		}
		printf("Max experience: %d\n",dp[max_cost]);
	}
	return 0;
}
/*
样例输入
2
3 10
7 7
2 3
3 5
2 5
3 5
2 1
样例输出
Max experience: 12
Max experience: 6
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 05:33:38

NYOJ 654 喜欢玩warcraft的ltl (01背包常数优化)的相关文章

NYOJ 654 喜欢玩warcraft的ltl

喜欢玩warcraft的ltl 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 ltl 非常喜欢玩warcraft,因为warcraft十分讲究团队整体实力,而他自己现在也为升级而不拖累团队而努力. 他现在有很多个地点来选择去刷怪升级,但是在每一个地点他都要买上充足的补给和合适的道具,以免在刷怪的时候被怪物反杀了,每一个地点的怪物打完了就没有了(还居然不掉金钱跟装备),而且他只要选定了地点就一定会刷完该地点全部的怪物,同时获得对应的经验值.现在ltl 能给出每一个地

NYOJ 654喜欢玩warcraft的ltl(01背包/常数级优化)

传送门 Description ltl 非常喜欢玩warcraft,因为warcraft十分讲究团队整体实力,而他自己现在也为升级而不拖累团队而努力. 他现在有很多个地点来选择去刷怪升级,但是在每一个地点他都要买上充足的补给和合适的道具,以免在刷怪的时候被怪物反杀了,每一个地点的怪物打完了就没有了(还居然不掉金钱跟装备),而且他只要选定了地点就一定会刷完该地点全部的怪物,同时获得对应的经验值.现在ltl 能给出每一个地点用来买补给和道具的钱和打完全部怪物所能获得的经验,但是他所拥有的钱是一定的.

喜欢玩warcraft的ltl

喜欢玩warcraft的ltl 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 ltl 非常喜欢玩warcraft,因为warcraft十分讲究团队整体实力,而他自己现在也为升级而不拖累团队而努力. 他现在有很多个地点来选择去刷怪升级,但是在每一个地点他都要买上充足的补给和合适的道具,以免在刷怪的时候被怪物反杀了,每一个地点的怪物打完了就没有了(还居然不掉金钱跟装备),而且他只要选定了地点就一定会刷完该地点全部的怪物,同时获得对应的经验值.现在ltl 能给出每一个地

nyoj 203 三国志(最短路加01背包)

三国志 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 <三国志>是一款很经典的经营策略类游戏.我们的小白同学是这款游戏的忠实玩家.现在他把游戏简化一下,地图上只有他一方势力,现在他只有一个城池,而他周边有一些无人占的空城,但是这些空城中有很多不同数量的同种财宝.我们的小白同学虎视眈眈的看着这些城池中的财宝. 按照游戏的规则,他只要指派一名武将攻占这座城池,里面的财宝就归他所有了.不过一量攻占这座城池,我们的武将就要留守,不能撤回.因为我们的小白手下有无数的武将,

【背包专题】F - Ahui Writes Word hdu3732【01背包+二进制优化】

We all know that English is very important, so Ahui strive for this in order to learn more English words. To know that word has its value and complexity of writing (the length of each word does not exceed 10 by only lowercase letters), Ahui wrote the

NYOJ 456 邮票分你一半(01背包)

邮票分你一半 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述      小珂最近收集了些邮票,他想把其中的一些给他的好朋友小明.每张邮票上都有分值,他们想把这些邮票分成两份,并且使这两份邮票的分值和相差最小(就是小 珂得到的邮票分值和与小明的差值最小),现在每张邮票的分值已经知道了,他们已经分好了,你知道最后他们得到的邮票分值和相差多少吗? 输入 第一行只有一个整数m(m<=1000),表示测试数据组数. 接下来有一个整数n(n<=1000),表示邮票的张数. 然

ZOJ 3812 We Need Medicine 01背包+位优化

题目链接:点击打开链接 #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #include <map> typedef unsigned long long ll; using namespace std; const int N = 400 + 1; const int M = 200000 + 1; int t[N], w[N], g[5

01背包的优化问题

通过不断的去模拟代码的运行 对背包问题有了更深的理解 sum[i][j]=max(sum[i-1][j],sum[i-1][j-x[i]]+v[i]); 实际上就是数据的不断更新过程 在上一子问题的基础上 对该子问题每个空间大小能放的最多价值进行更新 然后使用于下一个子问题  由于每个子问题都是最优解 最终得到的解就是最优解 下午的背包刚入手 用的是二维数组 有一定程度的浪费空间 对于一个子问题的每个空间对应的最佳价值 可以通过从高位到地位逆序的写法(下一个子问题求每个空间大小的最佳价值要使用的

NYOJ 527 AC_mm玩dota

AC_mm玩dota 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 大家都知道AC_mm比较喜欢玩游戏,特别是擅长war3这款经典游戏.某天AC_mm来到了VS平台上 ,准备去虐菜鸟,正巧一个不小心将我们ACM队长虐了 ^_^,我们的队长这下可不高兴了,说要出一道难题让AC_mm难堪一下.题目描述是这样的,给一个正整数n,n在二进制表示的情况下(不含前导0和符号位)有a个1和b个0,求斐波拉契数列的第a*b项对1314520取模后的值ans. 注意(斐波拉契数列: