NYOJ 654 喜欢玩warcraft的ltl -- 01背包 一中常数优化

博客介绍了在解决01背包问题时,如何通过常数优化减少循环次数,特别是针对《背包问题九讲》中一处笔误的修正,通过动态规划和倒推思路,提高了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个常数优化前面的伪代码中有for v=V..1,可以将这个循环的下限进行改进。
由于只需要最后dp[v]的值,倒推前一个物品,其实只要知道dp[v-w[n]]即可。以此类推,对以
第j个背包,其实只需要知道sumc[i->n](第i物品到最后一个物品的消耗和,因为前面的对结果没有影响)即可,即代码中的

1 for i -> 1 to N
2     do for v -> V to 0
3         do

可以改成:

1 for i -> 1 to n
2     do bound -> max(dp[V - sumc[i->n]], c[i]) // 《背包九讲》中这里笔误写错了。
3     for v -> V to bound
4         do
这对于V比较大时是有用的。
----- 摘自《背包问题九讲v1.1》
/*
http://acm.nyist.net/JudgeOnline/problem.php?pid=654
01背包 一中常数优化
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <time.h>
#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 inf     =  -(1<<30);
const int INF     =   (1<<30);
const int COST    =  1e6 + 10; 
const int M       =  1e4 + 10;

int dp[COST];
int v[M];
int c[M];

int main(){
	freopen("Input.txt","r",stdin);
	freopen("outcheck.txt","w",stdout);
	
	int Ncase;
	cin >> Ncase ;
	while(Ncase--){
		CLR(dp,0);
		int max_cost, n_bags,cost ,value;
		scanf("%d%d",&n_bags, &max_cost);
		for (int i = 1 ; i <= n_bags ; i++){ // max:1000
			scanf("%d%d" , &c[i] , &v[i]);
		}
		for (int i = 1 ; i <= n_bags ; i++){ // max:1000
			int sum = 0;
			for(int j = i ; j <= n_bags ; j++){
				sum += c[j];
			}
			int bound = Max(max_cost-sum , c[i]);
			for(int j = max_cost ; j >= bound ; j--){ // max:100 0000
				if( dp[j] < dp[j-c[i]] + v[i]){
					dp[j] = dp[j-c[i]] + v[i];
				}
			}
		}
		printf("Max experience: %d\n",dp[max_cost]);
	}
	cout << "pro_time cost:" << (double)clock()/CLOCKS_PER_SEC;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值