动态规划像一个生产车间有好多连续的生产线 一个阶段就是一个生产线 状态就是每个生产线物品的状态 决策就是生产线上根据物品的状态而对物品的操作.
01背包问题:
阶段: 第一生产线(放不放第一个物品)→第二生产线(放不放第二个物品)→.......→第N生产线(放不放第N个物品)
第一生产线共
有n-v1个选择: v=V时放不放 v=V-1时放不放.....v=V-v1时放不放
然后移交给第二生产线: 共
有n-v2个选择: v=V时放不放 v=V-1时放不放.....v=V-v2时放不放
......
然后移交给第N生产线: 共
有n-v(n)个选择: v=V时放不放 v=V-1时放不放.....v=V-v(n)时放不放
以第N生产线为例: 当v=V-i时 f[v]>f[v-v(n)]+w 不放 因为v=V-i时前面生产线已经生产出更好的产品了,没必要再加工了.
状态:
f[v]就是状态的存储结构,是连续的,表示产品每个部分的加工情况.
就像工厂里的一个大屏幕,上面记录着产品的每个部分的生产情况. 每个生产线都看着共享着.第一个生产线生产完了,把其记录在屏幕上,等第二生产线开始生产时参考,如果能生产出比第一生产线更优的产品则生产,否则不生产.
决策: 每个生产线共有很多的选择,产品有不同的状态,例如v可以从0 to V,先让第一生产先分别加工,再让第二生产线加工,如过某一个状态有比第一生产线生产的更优秀则重新加工.
第一个阶段(即只放第一个物品) 共有n-v1个状态(vi为第i个物品的重量)
第二个阶段 共有n-v2个状态
第n个阶段 共有n-v(n)个状态
阶段: 第i件物品放不放 共有n个阶段
决策:
是第 i件物品放或者不放
转移方程: f[v]=max(f[v],f[v-c]+w)
例如:
#include<cstdio>
#include<cstring>
#define max(x,y) x>y?x:y
int f[1005];
int main()
{ int n,V,c,w;
while(1)
{
scanf("%d%d",&n,&V);
if(!(n||V)) return 0;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&c,&w);
for(int v=V;v>=c;v--)
f[v]=max(f[v],f[v-c]+w);
}
printf("%d\n",f[V]);
}
}