5.11校内测试

5.11校内测试

Elevator

输入文件 输出文件
Elevator.in Elevator.out

【题目描述】(Elevator.cpp/c/pas)

信息大佬们想建造太空梯(用魔法石垒)进入太空。他们有k (1 ≤K ≤ 400)种不同类型的魔法石,每一种魔法石的高度为h(1 ≤ h≤100),数量为c (1 ≤ c ≤10),由于会受到太空辐射而失去魔力,每一种魔法石不能超过这种魔法石的最大建造高度a (1≤ a≤40000),试求利用这些魔法石所能修建的太空梯的最高高度。

【输入格式】

第一行为一个整数即k。第2行到第k+1行每一行有三个数,代表每种类型魔法石的特征,即高度h,限制高度a和数量c。

【输出格式】

一个整数,即修建太空梯的最大高度。

【输入样例】 【输出样例】

3 48

7 40 3

5 23 8

2 52 6

【样例说明】

15+21+12

最底下为3块石头2型,中间为3块石头1型,上面为6块石头3型。放置4块石头2型和3块石头1型是不可以的,因为顶端的石头1型的高度超过了40的限制。

分析:

根据所给的样例,发现全贪心是不可的,具有后效性,需用DP解决

本质为多重背包,将每个类型的石头,以最高限制高度由小到大排序(如果先盖最高限制大的,最高限制小的可能盖不了) (部分贪心)

多重背包转01背包 ----好写又好想 ,01背包不香吗

简单来说,本题的物品数量有上限,将第 \(i\) 种物品都分为对应数量的01背包的物品,得到数量为 \(\sum num\) 的01背包,按01背包做法即可。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<memory.h>
 
using namespace std;
 
struct Node
{
	int c,h,a;
}node[402];
 
int dp[40010];
 
void clear()
{
	memset(dp,0,sizeof(dp));
	memset(node,0,sizeof(node));
}
 
bool cmp(Node x,Node y)
{
	return x.a<y.a;
}
 
int main()
{
	int n;
	while(scanf("%d",&n)==1)
	{
		clear();
		for(int i=1;i<=n;i++)
			scanf("%d %d %d",&node[i].h,&node[i].a,&node[i].c);
		sort(node+1,node+n+1,cmp);
		int maxn=0;
		for(int i=1;i<=n;i++)//n种物品
		{
			for(int k=1;k<=node[i].c;k++)//物品数量受限
			{
				for(int j=node[i].a;j>=node[i].h;j--)//简单的01背包
				{
					dp[j]=max(dp[j],dp[j-node[i].h]+node[i].h);
					if(maxn<dp[j]) maxn=dp[j]; 
				}
			}
		}
		printf("%d\n",maxn);
	}
	return 0;
}

游戏

游戏(game.cpp, 64MB, 1秒)

【问题描述】

两个大佬Stan和Ollie正在玩一种数字游戏。给定两个正整数M和N,从Stan开始,取其中较大的一个数,减去较小的数的正整数倍,当然,得到的数K不能小于0。然后是Ollie,对刚才得到的数K,和M,N中较小的那个数,再进行同样的操作,…直到一个人得到了0,他就取得了胜利。下面是他们用(25,7)两个数游戏的过程:

Start: 25 7

Stan: 11 7 { 18 7, 11 7 , 4 7 均可能}

Ollie: 4 7

Stan: 4 3

Ollie: 1 3

Stan: 1 0

Stan赢得了游戏的胜利。

现在,假设他们“完美”地操作,谁会取得胜利呢?

【输入格式】

第一行为测试数据的组数C。

下面有C行,每行为一组数据,包含两个正整数M和N, M和N的范围不超过长整型

【输出格式】

对每组输入数据输出一行。

如果Stan胜利,则输出“Stan wins”;否则输出“Ollie wins”。

【输入和输出样例】

game.in Game.out
2 Stan wins
25 7 Ollie wins
24 15

题目分析:

打眼一看,和 GCD 貌似有些关系(雾,牵扯到了博弈论(这不重要),游戏的结束是直到一方为0,我们除了这能提前预判吗?

如果 $a/b=1 $ 的话,那么无论如何我们都只有一种方案 , 把a中拿去b个

而拿走以后并不能直接判断出来,所以需要继续递推,此时轮到另一个人摸石头,注意状态要反着标

如果\(b=0\),那么先手必胜,即当前操作人失败。

如果\(a/b>1\) , 先手具有主动权, 他可以决定对方的选择(在“完美”操作下),先手必胜

以样例为例

状态 减一倍 减两倍 减三倍
25 7 25 7 25 7
S 18 7 11 7 4 7
O 11 7 | 4 7 4 7 4 3
S 4 7 | 4 3 3 4 1 3
O 4 3 | 1 3 3 1 1 0
S 1 3 | 1 0 0 1 O
O 1 0 | S S O
S O | S S O

首先 \(a/b>1\) , 先手有很多选择,在之后 \(a/b=1\) 都只有一种选择,死磕下去,胜负取决于前边的选择减几倍

在完美的操作下,先手一定会赢。

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
bool dfs(ll a,ll b,int who)
{
	if(!b)     return false;
	if(a/b==1) return !dfs(b,a-b,who^1);
	if(a/b>1)  return true;
}
int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	ll k;
	scanf("%lld",&k);
	ll a,b;
	while(k--)
	{
		scanf("%lld%lld",&a,&b);
		if(a<b)  swap(a,b);
		if(dfs(a,b,1)) printf("Stan wins\n");
		else
			printf("Ollie wins\n");
	}
}

旅行商

题目描述

对国家的城市 1~n 编号,互质的编号城市修双向道路,其余不修,一名旅行商想知道从首都(编号1)经过每个城市恰好一次回到首都的路径数

输入格式

一个正整数n

输出格式

一个数表示答案 ,对 1000000007取模

输入样例

4

输出样例

2

爆搜拿30!!性价比最高

爆搜

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
long long sum;
const int maxn=30,maxm=100;
bool vis[50];
struct Edge{
	int next,to;        
}edge[maxm];
int head[maxn],num_edge;

void add_edge(int from,int to){
    edge[++num_edge].next=head[from];
    edge[num_edge].to=to;            
    head[from]=num_edge;             
}

int gcd(int a,int b){
	return b? gcd(b,a%b):a;
}

void dfs(int u ,int city)
{
    vis[u]=1;
	if(city==n){//临界条件
    	sum++;
    	sum%=1000000007;
		return;//回溯
	}
	for(int i=head[u];i;i=edge[i].next)
	    if(!vis[edge[i].to]) 
		{
		    dfs(edge[i].to,city+1);//下搜
		    vis[edge[i].to]=0; //恢复原状
		} 
}
int main()
{
	freopen("merchant.in","r",stdin);
	freopen("merchant.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n-1;i++)
	for(int j=i+1;j<=n;j++)
		if(gcd(i,j)==1) 
			{
				add_edge(i,j);
				add_edge(j,i);
			}
	//cout<<num_edge;//检验边数
	dfs(1,1);
	printf("%lld",sum);
	
}

等我在看懂标程后在更新吧QWQ

猜你喜欢

转载自www.cnblogs.com/wzy1744315462/p/12913821.html