您的位置:首页 > 其它

01背包问题合集

2017-03-19 01:35 387 查看
1.hdu 5616 Jam’s balance

Jim has a balance and N weights. (1≤N≤20)

The balance can only tell whether things on different side are the same weight.

Weights can be put on left side or right side arbitrarily.

Please tell whether the balance can measure an object of weight M.

Input

The first line is a integer T(1≤T≤5), means T test cases.

For each test case :

The first line is N, means the number of weights.

The second line are N number, i’th number wi(1≤wi≤100) means the i’th weight’s weight is wi.

The third line is a number M. M is the weight of the object being measured.

Output

You should output the “YES”or”NO”.

Sample Input

1

2

1 4

3

2

4

5

Sample Output

NO

YES

YES

dp[]为1时,表示可以拼凑出此重量;

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#include <stack>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=107;
int v
,w
;
int dp[2007];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));//dp每次记得初始化
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&v[i]);
dp[0]=1;//重量为0时dp[]=1便于后面的转移
for(int i=0;i<n;i++)
{
for(int j=2000;j>=v[i];j--)
{
if(dp[j-v[i]]) dp[j]=1;//逆着输入避免重复计数
}
}
for(int i=0;i<n;i++)
{
for(int j=v[i];j<
4000
;=2000;j++)
{
if(dp[j]) dp[j-v[i]]=1;//正着输入避免重复标记
}
}
int k;
scanf("%d",&k);
for(int i=0;i<k;i++)
{
int a;
scanf("%d",&a);
if(a>2000) puts("NO");
if(dp[a]) puts("YES");
else puts("NO");
}
}
}


2.hdu 1203 I NEED A OFFER!

Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。

Input

输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000)

后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。

输入的最后有两个0。

Output

每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。

Sample Input

10 3

4 0.1

4 0.2

5 0.3

0 0

Sample Output

44.0%

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#include <stack>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=10007;
int v
;
double w
;
double dp
;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m))
{
if(!n&&!m) break;
double tmp=1;
for(int i=0;i<N;i++)
dp[i]=1;
for(int i=0;i<m;i++)
{
scanf("%d%lf",&v[i],&w[i]);
}
for(int i=0;i<m;i++)
{
for(int j=n;j>=v[i];j--)
{
dp[j]=min(dp[j],dp[j-v[i]]*(1-w[i]));
}
}
printf("%.1f%%\n",(1-dp
)*100);
}
}


3.hdu 2955 Robberies

The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj .

Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .

Output

For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

Notes and Constraints

0 < T <= 100

0.0 <= P <= 1.0

0 < N <= 100

0 < Mj <= 100

0.0 <= Pj <= 1.0

A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.

Sample Input

3

0.04 3

1 0.02

2 0.03

3 0.05

0.06 3

2 0.03

2 0.03

3 0.05

0.10 3

1 0.03

2 0.02

3 0.05

Sample Output

2

4

6

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#include <stack>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=10007;
const double eps=1e-8;
double dp
;
double w[105];
int v[105];
int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}//控制精度
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
double vl;
int n;
scanf("%lf%d",&vl,&n);
vl=1-vl;
for(int i=0;i<n;i++)
{
scanf("%d%lf",&v[i],&w[i]);
w[i]=1-w[i];
}
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=10000;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]*w[i]);
}
}
for(int i=10000;i>=0;i--)
{
if(sgn(dp[i]-vl)>0)
{
printf("%d\n",i);
break;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: