拔尖班第一次作业:3. 大富翁的新规

【问题描述】

现有n块地板格子,序号从0到n-1,每块格子上有一个数字,以数组sum[n]的方式表示。现在要求你将这n块地板格子都踩过一遍,踩到序号为i的格子则可以获得sum[i-1]*sum[i]*sum[i+1]万元的资产,若i-1或者i+1超过了数组边界,则此时sum[i-1]*sum[i]*sum[i+1]式子中超出边界的元素数值记为1。按照什么样的顺序去踩地板才能获得最大资产呢?

【输入形式】

第一行输入n代表地板格子的个数,第二行输入n个数值,每个数值对应这n个格子上所标的数字
【输出形式】

输出一个数代表能获取的最大资产金额
【样例输入】

4

3 1 5 8
【样例输出】

167
【样例说明】

sum = [3,1,5,8]-->[3,5,8]-->[3,8]-->[8]-->[]

money = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
【评分标准】

因为此题要考虑到走格子的各种不同路径,故用DFS算法解决(水平有限,只能这样了QAQ):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[101],book[101],n,temp,cnt=-1;//开全局变量,便于函数访问 
class square{
	public:
	square()
	{
		turn=0;//初始化操作 
	}
		ll num;//格子上所标的数字 
		ll turn;//没遍历过的都为0,遍历过的都为1,每次循环结束后清零 
};
void dfs(ll step,square *arr)
{
	if(step==n+1)//每轮深搜结束 
	{
		temp=0;//每轮结束后temp恢复初始化,防止对下一轮遍历造成影响 
		for(ll i=1;i<=n;i++)
		{
			ll p,q;//左右两个数字,作用相当于指针,分别向左向右查找到第一个符合要求的方格 
			p=a[i]+1;q=a[i]-1;
			while(arr[p].turn!=0)
			{
				p++;
			}
			while(arr[q].turn!=0)
			{
				q--;
			}
			temp+=(arr[a[i]].num*arr[p].num*arr[q].num);
			arr[a[i]].turn=1;//表示已经访问过该格子,后续不再访问 
		}
		if(cnt<temp)
		{
			cnt=temp;//若一个轮回结束后遇到比自己大的cnt,则替换 
		}
		for(ll j=0;j<n+2;j++)
		{
			arr[j].turn=0;//这里本来想用fill的,结果忘了咋搞,于是省事直接for了 
		}
		return;
	}
	for(ll i=1;i<=n;i++)
	{
		if(book[i]==0)
		{
			a[step]=i;
			book[i]=1;//表示在深搜过程中已经遍历过 
			dfs(step+1,arr);//继续深搜 
			book[i]=0;//恢复初始状态 
		}
	}
	return;
}
int main()
{
	ll N;
	cin>>N;
	square arr[N+2];//此处N+2是为了防止数组越界,干脆我给他一个头一个尾,访问到头尾时一定停下 
	arr[0].num=1;arr[N+1].num=1;//按照题目要求,越界部分数字全为1 
	for(ll i=1;i<=N;i++)
	{
		cin>>arr[i].num;
	}
	n=N;
	dfs(1,arr);
	cout<<cnt<<endl;
	system("pause");
	return 0;
} 

PS:这种题不比期末那种磨人耗时间的大模拟强多了?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一二爱上蜜桃猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值