最近流行种苹果的游戏,玩家种下一颗苹果树,初始成长值为0,每次浇水都会增加成长值,当成长值大于等于V时,就可以收获成熟的苹果了。玩家拥有五种颜色(红色、黄色、蓝色、绿色、紫色)的水壶若干个,每浇水一次就消耗一个水壶,不同颜色的水壶水量不一定一样,因此用不同颜色的水壶浇水苹果树获得的成长值也可能不一样。苹果成熟后剩余水壶中的水量仍然可以继续在下一局游戏中继续使用,因此,玩家想用最少的水量让苹果成熟,最大程度节约水量。请你帮他计算下苹果成熟的最少浇水量。
输入格式:
输入第一行为一个整数T(1<=T<=100),代表测试数据的组数,每组数据的第一行为一个整数V(0<=V<=10^12),代表苹果成熟应达到的成长值,随后5行,每行包括三个整数N,G,W(0<=N<=1000,0<=W,G<=10^9),分别代表其中一种颜色水壶的个数,浇水后对应的成长值,水量,中间用空格分割,并且所有颜色水壶的总个数不超过1000。
输出格式:
每组数据都对应一行输出。如果苹果能够成熟,该行输出两个整数,分别代表苹果成熟时的最低浇水量和所获得的成长值。如果所有水壶的水量都浇上,苹果也成熟不了,则输出”Impossible!”。
输入样例:
3
100
20 5 5
16 10 4
3 20 10
15 2 2
5 8 6
60
2 3 2
3 5 6
1 3 5
2 6 1
3 4 2
50
2 20 10
3 10 20
2 5 6
20 4 10
12 6 5
输出样例:
40 100
Impossible!
30 52
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct my {
ll w, g;
int num;
double g_w;
bool operator<(const my& t) { return g_w > t.g_w; }
}tr[5];
ll ans = 1e18, sum, res = 0, sres = 0;
double n[5];
void dfs(ll V, int u) {
if (V <= 0) {
if (ans > res) {
ans = res;
sum = sres;
}
return;
}
if (u == 4) {
ll t = min((ll)tr[u].num, V / tr[u].g + 1);
if (t * tr[u].g >= V) {
if (ans > res + t * tr[u].w) {
ans = res + t * tr[u].w;
sum = sres + t * tr[u].g;
}
}
return;
}
if (V % tr[u].g == 0 && V / tr[u].g <= tr[u].num) {
if (ans > res + V / tr[u].g * tr[u].w) {
ans = res + V / tr[u].g * tr[u].w;
sum = sres + V;
}
}
else {
ll up = min((ll)tr[u].num, (ll)n[u] + 9), down = max(0ll, (ll)n[u] - 9);
for (int i = down; i <= up; i++) {
res += i * tr[u].w;
sres += i * tr[u].g;
dfs(V - i * tr[u].g, u + 1);
res -= i * tr[u].w;
sres -= i * tr[u].g;
}
}
}
void solve() {
ans = 1e18, sum = 0, res = 0, sres = 0;
ll Vt,V;
scanf("%lld", &V);
Vt = V;
for(int i=0;i<5;i++) n[i]=0;
for (int i = 0; i < 5; i++) { scanf("%d %lld %lld", &tr[i].num, &tr[i].g, &tr[i].w); tr[i].g_w = (double)tr[i].g / tr[i].w; } // 按性价比来排
sort(tr, tr + 5);
for (int i = 0; i < 5; i++) {
if (!V) break;
if (tr[i].g * tr[i].num >= V)
{ n[i] = (double)V / tr[i].g; //需要的瓶数
V = 0;
}
else V -= tr[i].g * tr[i].num, n[i] = tr[i].num;
}
dfs(Vt, 0);
if (ans == 1e18) puts("Impossible!");
else printf("%lld %lld\n", ans, sum);
}
int main() {
int Case;
cin >> Case;
while (Case--) solve();
return 0;
}
时间复杂度:O();