zhxのDP讲
作者:互联网
DP基础例题
1. 斐波那契数列
f[1]=1;//第0项和第1项
f[0]=0;
//记忆化搜索
int dp(int n)//斐波那契数列第n项
{
//g[i]表示f[i]有没有计算过
if(n<=1)return n;
if(g[n])return f[n];
g[n]=true;
f[n]=dp(n-1)+dp(n-2);
return f[n];//O(fn)
}
//其它求当前
for(int i=2;i<=a;i++)
f[i]=f[i-1]+f[i-2];
//O(n)
//当前求其它
for(int i=0;i<=n;i++)
{
//O(n)
f[i+1]+=f[i];
f[i+2]+=f[i];
}
2. 组合数
for (int i=0;i<=n;i++)
{
C[i][0] = 1;//处理边界
for (int j=1;j<=i;j++)
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
- IOI数字三角形及其系列
状态:f[位][置]=经过的数字之和
f[i][j]:走到 (i,j) 的数字最大和
//滑雪
n行m列
可以走任意四个方向
每走一步需要使得脚底数字变大
最多走几个格子
f[x][y]代表走到(x,y)的最长长度
若:a[x-1][y]>a[x][y];
f[x-1][y]=max(f[x-1][y],f[x][y]+1)
//不正确解,使用自己求其他
//但没有保证当前的位置求出
cin >> n >> m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
cin >> a[i][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
f[i][j]=1;
for (int x=1;x<=n;x++)
for (int y=1;y<=m;y++)
for (int d=上下左右)
{
int xx = x朝着d走;
int yy = y朝着d走;
if ( (xx,yy)存在 && a[xx][yy] > a[x][y]) f[xx][yy] = max(f[xx][yy],f[x][y]+1);
}
DP三要素:
- 状态
- 转移方程
- 边界条件
DP可加维度
f[i][j](二维)—f[i][j][k](三维)—f[i][j][k][l](四维)
若时间空间过高,削减冗余状态,减少维度
建一个和原来状态相同的数组储存方案或方案数
背包模型
背包DP
01背包
n个物品 背包容积为m
第i个物品体积为vi,价值为wi
需要向背包里装一定的物品,在体积不超限的情况下装价值最高的物品
f[编号][体积]=价值
f[i][j]表示考虑完前i个物品 背包已经使用了j的体积
//01背包
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
//v体积 w价值
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
//考虑求f[i][j]
f[i][j]=f[i-1][j];//第i个物品不选
if(j>=v[i])
f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i])
}
例题采药
无穷背包
n种物品 背包容积为m
每种物品数量不限
第i个物品体积为vi,价值为wi
f[i][j]表示考虑完前i种类物品 背包已经使用了j的体积
//无穷背包
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
//v体积 w价值
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
//考虑求f[i][j]
f[i][j]=f[i-1][j];//第i个物品不选
if(j>=v[i])
f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i])
}
例题疯狂的采药
有限背包(多重背包)
有N种物品和一个容量为T的背包,第i种物品最多有M[i]件可用,价值为P[i],体积为V[i]
求解:选哪些物品放入背包,可以使得这些物品的价值最大,并且体积总和不超过背包容量。
//有限(多重)背包
cin>>n>>m;
int k=0;
//v体积 w价值 u个数
for(int i=1;i<=n;i++)
{
int v_,w_,x_;
cin>>v_>>w_>>x_;
int r=1;
while(x_>=r)
{
k++;
v[k]=v_*r;
w[k]=w_*r;
x_-=r;
r*=2;
}
if(x_!=0){
k++;
v[k]=v_*x_;
w[k]=w_*x_;
}
}
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k*v[i]<=j&&k<=u[i];k++){
//考虑如何求f[i][j]
f[i][j]=max(f[i][j],f[i-1][j-kv[i]]+k*w[i]);
}
标签:背包,int,zhx,cin,体积,物品,DP 来源: https://www.cnblogs.com/DAIANZE/p/15024698.html