pascal 动态规划方程

来源:百度知道 编辑:UC知道 时间:2024/05/12 17:52:41
庆功会(party)
[问题描述]
八(1)班由于在期中考中获得了团体第一名,班主任吴老师决定开一场庆功会。于是购买东西的任务就交给了小李同学(钱由班会出)。由于小李同学四肢发达,头脑简单,于是这个任务便落到了你头上(当然不要你跑腿。跑腿是小李的事 ^_^)。

[输入格式]
第一行二个数n(n<=500),m(m<=5000),其中n代表希望购买的物品的种数,m表示班会拨给小李的钱数。
接下来n行,每行3个数,v、w、s,分别表示第I种物品的价格、价值(价格与价值是不同的概念)和购买的数量(只能买0件或s件),其中v<=100,w<=1000,s<=10。

[输出格式]
一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

[输入样例]
5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1

[输出样例]
1000

这个是很典型的背包问题。
既然你知道是动态规划问题,就要着眼于寻找状态转移方程。
用f(n,m)表示考虑用m钱来购买n件物品所能获得的最大价值。
用v[n]表示第n件物品的价格。w[n]表示第n件物品的价值。s[n]表示第n件物品的数量。
那么
f(n,m)=max{f(n-1,m) , f(n-1,m-v[n]*s[n])+s[n]*w[n]}
这个就是状态转移方程。
然后用记忆化搜索来实现。
参考如下
program cs;
var
n,m:longint;
v,w,s:array[0..500] of longint;
f:array[0..500,0..5000] of longint;
i,j:longint;

function fun(n,m:longint):longint;
var
i,j:longint;
temp,tempi:longint;

begin

if n=1 then
begin
if m-v[n]*s[n]>=0 then
begin
fun:=w[n]*s[n];
end else begin fun:=0; end;
end else
begin
if f[n,m]=123456 then
begin
temp:=fun(n-1,m);
if m-v[n]*s[n]>=0 then
begin
tempi:=fun(n-1,m-v[n]*s[n])+w[n]*s[n];