poj3093(背包最大容量)
2016-02-29 23:30
190 查看
链接:点击打开链接
题意:给定一个容量为D的背包和V件物品各自的体积,求有多少种方法使得背包再也装不下任何物品
代码:
题意:给定一个容量为D的背包和V件物品各自的体积,求有多少种方法使得背包再也装不下任何物品
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int w[1005],dp[1005],sum[1005]; int main(){ int t,n,v,i,j,k,ans,tmp; scanf("%d",&t); //当前容量装不下则表示没装的物品中体积最小的 for(k=1;k<=t;k++){ //也装不下,因此枚举最小的物品是哪一个 scanf("%d%d",&n,&v); memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++) scanf("%d",&w[i]); sort(w+1,w+n+1); for(i=1;i<=n;i++) sum[i]=sum[i-1]+w[i]; if(w[1]>v){ //最小的也装不下输出0 printf("%d 0\n",k); continue; } ans=0; dp[0]=1; for(i=n;i>=1;i--){ //优化在于从后往前枚举,因为从前往后枚举 tmp=v-sum[i-1]; //比当前枚举的值大的所有值,每次都会进行 for(j=max(0,tmp-w[i]+1);j<=tmp;j++) //01背包,因此从后枚举时避免了重复进行 ans+=dp[j]; for(j=v;j>=w[i];j--) //如果当前枚举的值是w[i],答案就是装满 dp[j]+=dp[j-w[i]]; //sum-w[i]+1~sum的所有总数的和,又因为 } //要保证当前值是剩下的值中最小的,因此 printf("%d %d\n",k,ans); //左右边界的容量都减去sum[i-1] } return 0; }
相关文章推荐
- 子类化的MFC方式
- 描述一下JVM加载class文件的原理机制
- Web应用class寻址顺序
- jsp中会话跟踪的总结
- 再水一发相同序列
- 《编写高质量代码:改善C++程序的150个建议》读书笔记3
- 文档对象模型操作xml文档
- android开发之路02(浅谈BroadcastReceiver)
- 数据仓库建设-业务数据调研
- 2016年2月之 1900
- CF 633C Trie
- Qt在线讲座之QML脚本书写规范
- windows 下一台服务器多个tomcat服务安装
- python提供了一个进行hash加密的模块:hashlib
- waitpid非阻塞时的用法
- Android 2016新技术
- 笔记本电脑突然无法连网
- PLSDA 构建 ROC曲线
- 子类化的SDK方式
- @override在MyEclipse和Eclipse中报注解annotation错误