【题目描述】
Tom将烹饪N道菜,编号分别为1到N。
第i道菜需要用烤箱连续烤Ti分钟,一个烤箱不能同时用于两道或两道以上的菜肴。
如果Tom有两个烤箱可供使用,那么烹调所有N道菜所需的最短时间是多少分钟?假
设除使用烤箱以外的所有过程所需的时间可以忽略不计。
【输入格式】
第一行输入一个整数N(1≤N≤100)。
第二行有N个整数T1,T2,…,TN(1≤Ti≤10^3)
【输出格式】
输出一个整数,表示需要的最短时间。【输入输出样例1】
5
8 3 7 2 5
13
【输入输出样例1说明】
例如,我们可以按如下方法使用两个烤箱,在13分钟内烹调完所有菜肴。
• 第一个烤箱:按顺序烹饪菜肴5和1。
• 第二个烤箱:按顺序烹饪菜肴2、4和3。
【输入输出样例2】
2
1000 11000
【输入输出样例3】
9
3 14 15 9 26 5 35 89 79138
在理想状态下,最好的方式就是每个烤箱用几乎一样的时间同时进行,这样的时间就一定是最短的,也就是先求平均值,然后设计程序逐步逼近所算出的平均值
依照这种思想,可以用0/1背包问题求解,把平均值看做背包最大容量,时间就是重量,找到小于平均值的最大时间和;
本题实质上就是0/1背包的变形(藏得很隐蔽啊)
附上AC代码
#include<bits/stdc++.h>
using namespace std;
int sum,n;
int f[100001];
int a[101];
int main()
{
// freopen("cook.in","r",stdin); freopen("cook.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
int ans=sum/2;
for(int i=1;i<=n;i++)
{
for(int j=ans;j>=a[i];j--)
{
f[j]=max(f[j],f[j-a[i]]+a[i]);
}
}
cout<<max(f[ans],sum-f[ans]);
return 0;
}
最后有一个比较是因为并不是每次的答案都在平均数左右,比如样例2中的答案就和平均数差距很远。
还要多练习啊