描述
沈宝宝的天玄石做的又丑又难看,戴尔廖实在是看不下去了,于是就出手帮助了他。
戴尔廖从怀中掏出了很多块神奇的石头,这些石头都是矿石结晶。每颗矿石结晶拥有着的人之精华,以及的地之精华。
戴尔廖缓缓道:“传说中,只要你拥有的石头的人之精华的和为,你拥有的石头的地之精华的和为,且除以恰好等于,拿这些石头去配比,就能得到完美的天玄石!”
沈宝宝一听,高兴的跳了起来!
戴尔廖说:“不急不急,这些石头我可不能白白给你,第颗石头,你需要付出的代价,我才会给你。”
这时,沈宝宝犯难了,沈宝宝究竟最少需要付出多少的代价,才能配比得到天玄石呢?
输入
第一行一个T,表示有T组测试数据。
接下来每组数据:
第一行为两个整数n和C,表示戴尔廖拥有的矿石结晶个数,以及配比需要的比值C。
接下来n行,每行三个整数,A[i],B[i],C[i],分别表示人之精华、地之精华和购买石头需要的代价。
数据满足:
1<=T<=10
1<=n<=100
1<=A[i],B[i]<=10
1<=c[i]<=10000
1<=C<=100
保证所有数据均为整数。
输出
对于每组数据,输出最少合成天玄石的代价,如果不能合成,输出“ShenBaoBao GG”
样例输入1
2
1 1
1 2 1
3 2
3 2 2
3 1 3
3 1 6
样例输出1
ShenBaoBao GG
5
思路:
dp[j][k]表示能量用了j的人之精华,k的地之精华的最小花费。
转移:dp[j][k] = min(dp[j][k],dp[j-a[i]][k-b[i]]+c[i]);
注意,这是一个01背包,所以你得倒着枚举这个状态,以保证状态不会覆盖。(或者你直接三维状态表示也可以。)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define mp(x,y) make_pair(x,y)
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//
const int maxn = 1e3+10;
int n,C,a[105],b[105],c[105];
int dp[maxn][maxn];
int main(){
int T = read();
while(T--){
memset(dp,INF,sizeof(dp));
cin >> n >> C;
for(int i=1; i<=n; i++)
cin >> a[i] >> b[i] >> c[i];
dp[0][0] = 0;
for(int i=1; i<=n; i++)
for(int j=maxn-1; j>=0; j--)
for(int k=maxn-1; k>=0; k--)
if(j>=a[i]&&k>=b[i])
dp[j][k] = min(dp[j][k],dp[j-a[i]][k-b[i]]+c[i]);
int ans = INF;
for(int i=1; i<maxn; i++)
for(int j=1; j<maxn; j++){
if(i%j==0 && i/j==C){
ans = min(ans,dp[i][j]);
}
}
if(ans == INF)
cout << "ShenBaoBao GG\n";
else
cout << ans << endl;
}
return 0;
}