zju 2955 DP + 贪心归约
来源:互联网 发布:软件版权声明怎么写 编辑:程序博客网 时间:2024/05/01 22:11
无限重数多重背包,
问题描述:有物品集V[0...n-1],每个物品都有无限个,背包大小为C,求取得C大小背包的最小物品个数。
f[0]=0;
f[i]=min{f[i-V[j]]+1 | j=0,1,...n-1 };
当C很大n不大时的优化方法,设vm=max{V[0...n-1]},根据Frobenius Number进行保守估算,当C>=vm*n是恒有解的
因此,只要DP求得C属于[0,vm*n+vm)上的最优解,当C<vm*n+vm时,直接输入最优解,
当C>=vm*n+vm时,一定可以贪心归约到区间[vm*n,vm*n+vm)上。
#include <iostream>
#include <algorithm>
using namespace std;
int dp[10001];
int M[100];
int main()
{
int T;
scanf("%d",&T);
while(T--){
int m,n;
scanf("%d%d",&m,&n);
for(int i=0;i<m;i++){
scanf("%d",&M[i]);
}
fill(dp,dp+10001,100000);
dp[0]=0;
for(int i=1;i<=10000;i++){
for(int j=0;j<m;j++){
if(i>=M[j]){
dp[i]<?=dp[i-M[j]]+1; //如果dp[i] < dp[i-M[j]]+1 ,则dp[i] = dp[i-M[j]]+1
}
}
}
if(n<=10000){
printf("%d/n",dp[n]<100000?dp[n]:-1);
}
else {
int x=*max_element(M,M+m);
int k=(n-10000+x-1)/x; //贪心归约到区间内
n-=x*k;
printf("%d/n",dp[n]<100000?dp[n]+k:-1);//如果无限重数多重背包,
}
}
}
- zju 2955 DP + 贪心归约
- 问题的归约
- 数据归约
- MPI中的归约
- 数据归约
- 2.2 问题归约表示
- MPI聚合通信之归约操作
- MapReducer中的多次归约处理
- MapReducer中的多次归约处理
- 编译原理的归约和推导
- 第5章-维度归约
- CUDA学习(归约算法)
- 数据预处理_数据归约03
- Java8 Stream 归约 使用示例
- 数据挖掘之数据归约
- python 归约、合拢、累加 函数
- zju 1234 Chopsticks (DP)
- zju 1013 dp
- JAVA处理日期(Date)时间(Time)以及相关类的介绍
- UI设计基础--图形设计
- 模拟string类
- javascript页面跳转常用代码
- 读取一个文件夹下大批的数据
- zju 2955 DP + 贪心归约
- C++ Source Network
- 好似不错
- VS2008。。。
- 利用VS.NET 宏生成属性定义以加快开发速度
- 【转】十个习惯让你精通新的开发技术
- Java谜题4——异常谜题
- 用js添加table的行和删除行
- 远程重启计算机(C#)