4013多重部分和问题
难度级别:B; 运行时间限制:2000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述
n种大小不同的数字 Ai,每种各Mi个,判断是否可以从这些数字之中选出若干个使他们的和恰好为K。
输入
第一行为两个正整数n,K。
第二行为n个数Ai,以空格隔开。
第三行为n个数Mi,以空格隔开。
输出
若可行则输出"yes"
否则输出"no"
输入示例
3 17
3 5 8
3 2 2
输出示例
yes
其他说明
1<=n<=100
1<=K<=50000
1<=Ai<=40
1<=Mi<=50

若数字相同对程序并无影响。

题解:此题有四个层次:

1.枚举bool乱搞:

 //标程4
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
bool d[maxn][maxm];int n,tar,A[maxn],num[maxn];
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){
memset(d,false,sizeof(d));
n=read();tar=read();
for(int i=;i<n;i++) A[i]=read();
for(int i=;i<n;i++) num[i]=read();
return;
}
void work(){
d[][]=true;
for(int i=;i<n;i++)
for(int j=;j<=tar;j++)
for(int k=;k<=num[i]&&k*A[i]<=j;k++)
d[i+][j]|=d[i][j-k*A[i]];
if(d[n][tar]) puts("yes");
else puts("no");
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}

2.快看窝萌还可以滚动,好神奇!

 //标程3
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
bool d[][maxm];int n,tar,A[maxn],num[maxn];
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){
memset(d,false,sizeof(d));
n=read();tar=read();
for(int i=;i<n;i++) A[i]=read();
for(int i=;i<n;i++) num[i]=read();
return;
}
void work(){
int tc=;d[tc][]=true;
for(int i=;i<n;i++){
tc^=;
for(int j=;j<=tar;j++)
for(int k=;k<=num[i]&&k*A[i]<=j;k++)
d[tc][j]|=d[tc^][j-k*A[i]];
}
if(d[tc][tar]) puts("yes");
else puts("no");
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}

3.窝萌还可以搞出正好凑成k的:

 //标程2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
int d[][maxm],n,tar,A[maxn],num[maxn];
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){
memset(d,-,sizeof(d));
n=read();tar=read();
for(int i=;i<n;i++) A[i]=read();
for(int i=;i<n;i++) num[i]=read();
return;
}
void work(){
int tc=;d[tc][]=;
for(int i=;i<n;i++){
tc^=;
for(int j=;j<=tar;j++){
if(d[tc^][j]>=) d[tc][j]=num[i];
else if((j>=A[i]&&d[tc][j-A[i]]>=)&&d[tc^][j]) d[tc][j]=d[tc][j-A[i]]-;
else d[tc][j]=-;
}
}
if(d[tc][tar]>=) puts("yes");
else puts("no");
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}

4.快看窝萌还可以滚动,好神奇!

 //标程1
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
int d[maxm],n,tar,A[maxn],num[maxn];
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
void init(){
memset(d,-,sizeof(d));
n=read();tar=read();
for(int i=;i<n;i++) A[i]=read();
for(int i=;i<n;i++) num[i]=read();
return;
return;
}
void work(){
d[]=;
for(int i=;i<n;i++){
for(int j=;j<=tar;j++){
if(d[j]>=) d[j]=num[i];
else if((j>=A[i]&&d[j-A[i]]>=)&&d[j]) d[j]=d[j-A[i]]-;
else d[j]=-;
}
}
if(d[tar]>=) puts("yes");
else puts("no");
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}

结论:然并卵。

COJ 0557 4013多重部分和问题的更多相关文章

  1. POJ_1742_Coins_(动态规划,多重部分和)

    描述 http://poj.org/problem?id=1742 n种不同面额的硬币 ai ,每种各 mi 个,判断可以从这些数字值中选出若干使它们组成的面额恰好为 k 的 k 的个数. 原型: n ...

  2. 编程算法 - 多重部分和问题 代码(C)

    多重部分和问题 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有n种不同大小的数字a, 每种各m个. 推断能否够从这些数字之中选出若干使它们的 ...

  3. HDU2844(多重部分和)

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  4. 多重部分和 poj1742

    Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...

  5. 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  6. 题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  7. DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数

    当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...

  8. POJ1742 coins 动态规划之多重部分和问题

    原题链接:http://poj.org/problem?id=1742 题目大意:tony现在有n种硬币,第i种硬币的面值为A[i],数量为C[i].现在tony要使用这些硬币去买一块价格不超过m的表 ...

  9. POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )

    题意 : 有 n 种面额的硬币,给出各种面额硬币的数量和和面额数,求最多能搭配出几种不超过 m 的金额? 分析 : 这题可用多重背包来解,但这里不讨论这种做法. 如果之前有接触过背包DP的可以自然想到 ...

随机推荐

  1. SpriteKit所有的类

    1.SKAction 2.SKCropNode 3.SKEffectNode 4.SKEmitterNode 5.SKKeyframeSequence 6.SKLabelNode 7.SKNode 8 ...

  2. 二维码_encode与decode

    二维码encode和decode工具类 import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.Buffere ...

  3. c#委托中另外一种用法

    在c#委托中,经常可能遇到函数重载的情况,可是又需要在一个函数中调用这些函数,一般我都是根据多个函数重载个数,也写上这么多个函数重载.比如 public double T1(int r) { retu ...

  4. Genymotion 模拟器 VirtualBox

    准备 介绍: 1.Genymotion安卓模拟器其实不是普通的模拟器,严格来说,genymotion是虚拟机,被网传定义为模拟器,加载APP的速度比较快,操作起来也很流畅.2.Genymotion依赖 ...

  5. ssh注解开发

    引入需要的jar包 @Entity public class Teacher { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) priva ...

  6. C#总结项目《影院售票系统》编写总结二

    昨天发布了总结项目的第一篇,需求分析以及类的搭建,今天继续更新,动态绘制控件.票类型的切换以及数据在窗体中的展现. 先从简单的开始,票类型的切换. 分析: 1.当点击普通票时 学生折扣和赠送者是禁用的 ...

  7. C#面向对象的一些笔记

    抽象 抽象类通常表示一个抽象的概念,提供一个继承的出发点.当设计抽下类时候,尽可能的拥有更多的相同代码,更少的数据. 抽象类.方法用abstract关键字修饰: 抽象成员不能是private. 抽象类 ...

  8. 【※索引】mysql索引常用命令

    索引分单列索引和组合索引.单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引.组合索引,即一个索包含多个列. MySQL索引类型包括: (1)普通索引 这是最基本的索引,它没 ...

  9. Sql 中常用日期转换Convert(Datetime)

    CONVERT(data_type,expression[,style]) convert(varchar(10),字段名,转换格式) 说明:此样式一般在时间类型(datetime,smalldate ...

  10. MySQL的truncate table 和source 命令

    1. truncate table XXX     在测试时,我很讨厌某表的主键一直自增长下去,总觉得从1开始最舒服,^_^,truncate table 就可以帮我,相比delete from 来说 ...