Description
某国成立了一个新的航空公司。该公司准备采购飞机来运营属下的两条航线A与B。他们联系了一些飞机制造商,这些制造商提供了他们飞机的资料。
资料里面记录了每种飞机的载客量,以及他们飞航线A与航线B所需要的燃油量。
通过市场调查,该公司摸清了两条航线的日均客流量。已知该航空公司每日能够采购到一定数目的燃油。目前,该公司在制定采购计划,
对于所有型号的飞机,他们可以采购任意数目。然而,他们正在怀疑,在燃油数目的限制下,他们的采购能否可以满足两条航线的客流量。
请写一个程序解决这个问题,作出回答。
输入格式
测试数据包括多组样例。数据以CASE开头,表示测试样例的数目。
对于每组样例,第1行有两个整数,n与fuel,表示供航空公司采购的飞机种类数目,以及他们每日能够采购到的燃油数目。
(1<=n<=1000, 0<=fuel <= 1000)
第2行有两个整数:p1,p2,表示两条航线每日的客流量。
第3行有n个整数:c1,c2,…,cn,每个数字表示第i个型号的飞机的载客量。
第4行有n个整数:f11,f12,…,f1n,每个数字表示第i个型号的飞机飞航线A的耗油量。
第5行有n个整数:f21,f 22,…,f2n,每个数字表示第i个型号的飞机飞航线B的耗油量。
输出格式
对于每个样例的输出均为一行,包括一个数字:0或者1。
如果采购商给出的飞机列表在燃油的限制条件下,能够满足两条航线的客流,输出1,否则输出0。
输入样例
2
3 16
299 499
100 200 250
2 3 4
3 5 6
3 17
299 499
100 200 250
2 3 4
3 5 6
输出样例
0
1
提示
第一个样例中,有3种飞机可供采购。但是由于每日燃油的限制,无论如何采购,都无法满足两条航线的载客任务。
第二个样例中,有3种飞机可供采购。航线A需要两架飞机运营:第1种飞机1架,第2种飞机1架。航线B需要2架飞机运营:第三种飞机2架。
这个解决方案每日的耗油量是2+3+6+6=17,满足题目要求。
解题思路
计算满足每条航线客运量的最低耗油量 amin,bmin,
totoal = amin + bmin
判断total和可用油量的大小关系即可
最低耗油量计算:
因为每架飞机有载客量和耗油量的概念,所以每条航线的计算都可以当成背包问题
又因为每个型号的飞机可以购买无限架,所以是完全背包问题。
先按一般的完全背包解法求出F[ i ] [ j ],F[ i ] [ j ]表示前 i 个物品在容量为 j 的情况
下所能得到的最大价值(在这里就表示前 i 种飞机在耗油量为 j 的情况下的最大载
客量
然后遍历F[ i ] [ j ]求出满足客运量的最低耗油量
#include<stdio.h>
#include<string.h>
int max(int a, int b){return a > b ? a : b;}
int getMin(int n, int fuel, int total, int value[], int weight[]);
int flag[1001][1001];
int main()
{
int t, n, fuel, atotal, btotal, amin, bmin, value[1002], aweight[1002], bweight[1002];
scanf("%d", &t);
while(t --)
{
scanf("%d %d", &n, &fuel);
scanf("%d %d", &atotal, &btotal);
for(int i = 0; i < n; i ++)
scanf("%d", &value[i]);
for(int i = 0; i < n; i ++)
scanf("%d", &aweight[i]);
for(int i = 0; i < n; i ++)
scanf("%d", &bweight[i]);
amin = getMin(n, fuel, atotal, value, aweight);
bmin = getMin(n, fuel, btotal, value, bweight);
printf("%d\n", amin + bmin > fuel ? 0 : 1);
}
return 0;
}
int getMin(int n, int fuel, int total, int value[], int weight[])
{
int f[1001], min = -1;
memset(f,0,sizeof(f));
memset(flag,0,sizeof(flag));
// 解完全背包
for(int i = 0; i < n; i ++)
{
for(int j = weight[i]; j < fuel; j ++)
f[j] = max(f[j], f[j - weight[i]] + value[i]);
// 记录
for(int k = 0; k < fuel; k ++)
flag[i][k] = f[k];
}
for(int i = 0; i < fuel; i ++)
for(int j = 0; j < n; j ++)
if(flag[j][i] >= total)
{
min = i;
goto M;
}
M: if(min == -1)
min = 10000000;
return min;
}