Zombie’s Treasure Chest

3 篇文章 0 订阅

Zombie’s Treasure Chest

这道题一看就用了完全背包,结果毫无疑问的挂了,看了一些大佬的解析后,发现有两种做法,一种是直接列举,另一种是通过最小公倍数的方法。

题意

有一个体积为N的箱子和两种数量无限的宝物。 宝物1的体积为S1,价值为V1;宝物2的体积为S2,价值为V2。你的任务是计算最多能装多大价值的宝物。

思路

枚举一:当s1和s2的体积很小,N很大的时候,由题意可知:s2个宝物1和s1个宝物2的体积相等,价值分别为s2v1和s1v2。所以当前者比较大的时候,宝物2最多s1-1个,因为以上的条件可知,当体积相等的条件下宝物1的价值大,所以宝物2不能再超出那个范围了,这样宝物1就不能放到最大化,总价值就不是最大化。后者较大时同理。 所以将俩种宝物都枚举后取最大的。
枚举二:当s1或s2的体积很大(即n/s1 n/s2 很小)时,枚举较大体积的那个宝物即可。

解法一

这些都要注意longlong

//#include <bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include <cmath>
#include <cstring>
using namespace std;
#define LL long long
int t;
LL n,s1,s2,v1,v2;

//求最大公约数
LL gcd(LL a,LL b){
	/*int temp=0;
	while(b!=0){
		temp=a%b;
		a=b;
		b=temp;
	}
	return a;*/
	return b?gcd(b,a%b):a;
} 

LL max(LL a,LL b){
	return a>b?a:b;
}

LL Lcm(LL a,LL b){
	return a/gcd(a,b)*b;
}

int main(){
	cin>>t;
	int Case=0;
	while(t--){
		cin>>n>>s1>>v1>>s2>>v2;
		LL lcm=Lcm(s1,s2);
		LL r=n%lcm,ans=0;
		if(s1<s2){
			LL temp=s1;
			s1=s2;
			s2=temp;
			temp=v1;
			v1=v2;
			v2=temp;
		}
		//容器容量小于两种宝物的最小公倍数 
		//暴力枚举每一种填充的情况 
		if(n/lcm==0){
			for(int i=0;i<=r/s1;i++){
				ans=max(ans,i*v1+(r-i*s1)/s2*v2);//这里为什么是r/s1呢,是因为这些宝石不能被割 
			}
		}else{
			//同样也是暴力枚举,但由于容器容量大于等于最小公倍数,所有还有部分
			//剩余空间可利用,要加上 
			for(int i=0;i<=(r+lcm)/s1;i++)
				ans=max(ans,i*v1+(r+lcm-i*s1)/s2*v2);
			ans+=(n-lcm)/lcm*max(lcm/s1*v1,lcm/s2*v2);
		}
		cout<<"Case #"<<++Case<<": "<<ans<<endl;
	}
	return 0;
} 

解法二

//#include <bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include <cmath>
#include <cstring>
using namespace std;
#define LL long long
int t;
LL n,s1,s2,v1,v2,maxn;
LL max(LL a,LL b){
	return a>b?a:b;
}

int main(){
	cin>>t;
	int Case=0;
	while(t--){
		cin>>n>>s1>>v1>>s2>>v2;	
		//一般把大的放在前面 
		if(s1>s2){
			swap(s1,s2);
			swap(v1,v2);
		}
		LL ans=0;
		//s1s2都很小
		//当n/s1和n/s2都非常大的时候,s1和s2都可以 
		if(n/s2>=65536){//65536是2的16次方,题目要求是适合32位有符号的整数 
			for(LL i=0;i<=s1;i++)
				ans=max(ans,i*v2+(n-i*s2)/s1*v1);
			for(LL i=0;i<=s2;i++)
				ans=max(ans,i*v1+(n-i*s1)/s2*v2);
		}else{//因为数据交换的原因,s2要大一些,所以n/s2要小些,此时枚举宝物2的个数 
			for(LL i=0;s2*i<=n;i++)
				ans=max(ans,i*v2+(n-i*s2)/s1*v2);
		}
		cout<<"Case #"<<++Case<<": "<<ans<<endl;
	}
	return 0;
} 
好的,让我们来创建一个用 TypeScript 编写的 Zombie Apocalypse 游戏。 首先,我们需要定义一些游戏中会用到的类型。例如,我们需要定义一个 `Player` 类型来代表游戏中的玩家: ```typescript interface Player { name: string; health: number; attack: number; defense: number; } ``` 接下来,我们需要定义一个 `Zombie` 类型来代表游戏中的僵尸: ```typescript interface Zombie { health: number; attack: number; defense: number; } ``` 然后,我们需要定义一个 `Game` 类来管理游戏状态和逻辑: ```typescript class Game { private player: Player; private zombies: Zombie[]; constructor(player: Player, zombies: Zombie[]) { this.player = player; this.zombies = zombies; } play() { while (this.player.health > 0 && this.zombies.length > 0) { const zombie = this.zombies[0]; const playerDamage = this.player.attack - zombie.defense; const zombieDamage = zombie.attack - this.player.defense; if (playerDamage > 0) { zombie.health -= playerDamage; } if (zombie.health <= 0) { this.zombies.shift(); } if (zombieDamage > 0) { this.player.health -= zombieDamage; } } if (this.player.health > 0) { console.log('You win!'); } else { console.log('You lose!'); } } } ``` 最后,我们可以创建一个游戏实例并开始游戏: ```typescript const player: Player = { name: 'John', health: 100, attack: 10, defense: 5, }; const zombies: Zombie[] = [ { health: 20, attack: 5, defense: 2 }, { health: 30, attack: 7, defense: 3 }, { health: 40, attack: 10, defense: 4 }, ]; const game = new Game(player, zombies); game.play(); ``` 这就是用 TypeScript 编写的 Zombie Apocalypse 游戏。当然,你可以根据自己的喜好和需求对代码进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值