喵哈哈村的魔法考试 Round #1 (Div.2) C 喵哈哈村的魔法石(II) 背包dp

点击打开链接

描述
沈宝宝的天玄石做的又丑又难看,戴尔廖实在是看不下去了,于是就出手帮助了他。
戴尔廖从怀中掏出了很多块神奇的石头,这些石头都是矿石结晶。每颗矿石结晶拥有着的人之精华,以及的地之精华。
戴尔廖缓缓道:“传说中,只要你拥有的石头的人之精华的和为,你拥有的石头的地之精华的和为,且除以恰好等于,拿这些石头去配比,就能得到完美的天玄石!”
沈宝宝一听,高兴的跳了起来!
戴尔廖说:“不急不急,这些石头我可不能白白给你,第颗石头,你需要付出的代价,我才会给你。”
这时,沈宝宝犯难了,沈宝宝究竟最少需要付出多少的代价,才能配比得到天玄石呢?

输入
第一行一个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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值