hdu 2191 单调队列优化
2012-07-24 17:05
218 查看
F[i][j] = max { F[i - 1] [j – k * v[i] ] + k * w[i] } (0 <= k <= m[i]) 是朴素的多重背包的转移公式
假设 v[i]为容量 w[i]为价值 no[i]为数量
a = j / v[i] 即a为i种物品最大可能使用次数。 b = j % v[i] 即不能用i种物品表达的价值。
则朴素转移公式可化为: F[i][j] = max { F[a*v[i] + b - k*v[i] ] + (a-k)*w[i] }
用 k 代替 a - k 得 F[i][j] = max { F[i-1][ k * v[i] + b] - k*[w] } + a*w[i] 其中 (k : 0 --> j /a)
单调队列就是用来算F[i][j] - a*w[i] 的最值的。
hdu 2191的 代码:
假设 v[i]为容量 w[i]为价值 no[i]为数量
a = j / v[i] 即a为i种物品最大可能使用次数。 b = j % v[i] 即不能用i种物品表达的价值。
则朴素转移公式可化为: F[i][j] = max { F[a*v[i] + b - k*v[i] ] + (a-k)*w[i] }
用 k 代替 a - k 得 F[i][j] = max { F[i-1][ k * v[i] + b] - k*[w] } + a*w[i] 其中 (k : 0 --> j /a)
单调队列就是用来算F[i][j] - a*w[i] 的最值的。
hdu 2191的 代码:
#include<iostream> #include<string.h> using namespace std; typedef struct { int x,t; }Q; int f[110]; int v[110],w[110],no[110]; Q ux[110]; int n,m; int fabs(int x) { if(x<0) return -x; return x; } int main() { int ti; int s,t; scanf("%d",&ti); while(ti--) { scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%d%d%d",&v[i],&w[i],&no[i]); memset(f,0,sizeof(f)); for(int i=0;i<m;i++) { for(int j=0;j<v[i];j++) //使用当前i种物品时,不可能达到的情况,j=0~~n/v[i] { s=0; t=-1; for(int k=0;k<=(n-j)/v[i];k++)//当前i种物品可能使用次数 { int temp=f[j+k*v[i]]-k*w[i];//一下求max{f[(a-k)v+b}-(a-k)v即f[kv+j]-kv} while(ux[t].x<temp&&s<=t) t--; ux[++t].x=temp; ux[t].t=k; while(fabs(ux[t].t-ux[s].t)>no[i]&&s<=t) s++; f[j+k*v[i]]=ux[s].x+k*w[i]; } } } printf("%d\n",f ); } return 0; }
相关文章推荐
- HDU 2191 二进制优化 和 单调队列优化
- hdu 2191 (多重背包的单调队列优化)
- hdu 2191(单调队列优化多重背包模板)
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 单调队列优化dp
- hdu 3401 单调队列优化DP
- Subsequence - HDU 3530 单调队列优化
- 股票交易 【SCOI 2010】HDU 3401 (单调队列优化DP入门)
- HDU 3401 Trade 【DP+单调队列优化】
- HDU 3401 Trade dp+单调队列优化
- hdu 3401 Trade 单调队列优化dp
- hdu-3401-Trade-单调队列优化的DP
- hdu 1171 Dividing 单调队列优化dp
- HDU 5945 (线性dp+单调队列优化)
- HDU 4374 One hundred layer DP的单调队列优化
- HDOJ 2191 (多重背包/二进制分解/单调队列优化DP)
- HDU 3401 Trade (单调队列优化DP)
- hdu 4374 单调队列优化dp
- hdu 3514 dp + 单调队列优化
- hdu 3530 Subsequence(dp单调队列优化)
- HDU 4374 单调队列优化 DP