【bzoj3163】 HEOI2013Eden的新背包问题 多重背包
2015-08-07 12:36
363 查看
跪POPOQQQ神犇,一直在往容斥和2287的方向上想,虽然很明显不可行,其实只需要枚举左半边选多少右半边选多少就可以了,或者说的吊一点就是把左边看成一个泛化背包,右边看成一个泛化背包然后合并就好了。第一次写多重背包好激动呀!!!
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[1010],b[1010]; int w[1010],v[1010],c[1010]; int f[1010][1010],g[1010][1010]; int n,m=1000,T,l,r; void insert(int x,int y) { while (l<=r && b[r]<y) r--; b[++r]=y;a[r]=x; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d%d",&v[i],&w[i],&c[i]); memset(f,0,sizeof(f)); for (int i=1;i<=n;i++) { if (c[i]*v[i]>m) c[i]=m/v[i]; for (int d=0;d<v[i];d++) { l=1,r=0; for (int j=0;d+j*v[i]<=m;j++) { insert(j,f[i-1][d+j*v[i]]-j*w[i]); if (j-a[l]>c[i]) l++; f[i][d+j*v[i]]=b[l]+j*w[i]; } } } memset(g,0,sizeof(g)); for (int i=n;i>=1;i--) { for (int d=0;d<v[i];d++) { l=1,r=0; for (int j=0;d+j*v[i]<=m;j++) { insert(j,g[i+1][d+j*v[i]]-j*w[i]); if (j-a[l]>c[i]) l++; g[i][d+j*v[i]]=max(g[i+1][d+j*v[i]],b[l]+j*w[i]); } } } scanf("%d",&T); while (T--) { int x,y; scanf("%d%d",&x,&y); x++; int ans=0; for (int i=0;i<=y;i++) ans=max(ans,f[x-1][i]+g[x+1][y-i]); printf("%d\n",ans); } return 0; }
相关文章推荐
- Altova XMLSpy格式化json的问题
- Java核心技术第9版中文扫描版
- Array()
- Remove Duplicates from Sorted List
- 遗觉&想象
- Unity3D合并着色器
- 天生我才必有用,关键你知道你适合做什么!
- Java 使用线程池递归压缩一个文件夹下的所有子文件
- 零基础学python-模块的导入与重载
- 移动手机端0.5px线条
- 零基础学python-模块的导入与重载
- ssh连接失败,排错经验
- 用两种方法实现一个点绕着另一个点旋转
- It's about trust
- SRM 624 Building Heights DivI 解读
- JavaSE----面向对象(多态、抽象类、接口)
- org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
- 大公司和小公司的抢人战,孰胜孰负?
- mysql中字符串的连接
- A* 算法详解