劳役结合的第五天

菜死我了

我是废物

我是厕所清道夫

大盗阿福

题目描述

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。
这条街上一共有 NN 家店铺,每家店中都有一些现金。
阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。
作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。
他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
输入格式
输入的第一行是一个整数 TT,表示一共有 TT 组数据。
接下来的每组数据,第一行是一个整数 NN ,表示一共有 NN 家店铺。
第二行是 NN 个被空格分开的正整数,表示每一家店铺中的现金数量。
每家店铺中的现金数量均不超过1000。

输出格式

对于每组数据,输出一行。
该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。

样例

输入样例

2
3
1 8 2
4
10 7 6 14

输出样例

8
24

样例解释

对于第一组样例,阿福选择第2家店铺行窃,获得的现金数量为8。
对于第二组样例,阿福选择第1和4家店铺行窃,获得的现金数量为10+14=24。

#include<bits/stdc++.h>
using namespace std;
int n,w[100861],t,f[100861];
int main()
{
	cin>>t;
	while(t--)
	{
		memset(f,0,sizeof(f));
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&w[i]);
		f[1]=w[1];
		for(int i=2;i<=n;i++)
		{
			f[i]=max(f[i-1],f[i-2]+w[i]); 
		}
		cout<<f[n]<<endl;
	}
	return 0;
} 

这题算dp中比较水的了,f[i]表示在第i个店铺时最多偷多少,而现在的状态有可能是从……不知道咋说,看图
在这里插入图片描述
如果f[i]继承了f[i-1]就不能偷w[i],所以比较f[i-1]和f[i-2]+w[i]即可,算是一道淼题了。

股票买卖 IV

题目描述

给定一个长度为 NN 的数组,数组中的第 ii 个数字表示一个给定股票在第 ii 天的价格。
设计一个算法来计算你所能获取的最大利润,你最多可以完成 kk 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。一次买入卖出合为一笔交易。

输入格式

第一行包含整数 NN 和 kk,表示数组的长度以及你可以完成的最大交易数量。
第二行包含 NN 个不超过 1000010000 的正整数,表示完整的数组。

输出格式

输出一个整数,表示最大利润。

样例

输入样例1

3 2
2 4 1

输出样例1

2

输入样例2

6 2
3 2 6 5 0 3

输出样例2

7

样例解释

样例1:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
样例2:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。共计利润 4+3 = 7。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=1e2+10;
int n,k,f[N][M][2],ans,a[N];
int main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	memset(f,-10,sizeof(f));
	for(int i=0;i<=n;i++)
		f[i][0][0]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=k;j++)
		{
			f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+a[i]);
			f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0]-a[i]);
		}
	}
	for(int i=1;i<=k;i++)
		ans=max(f[n][i][0],ans);
	cout<<ans;
	return 0;
}

然后开始写文化课作业。
然后

能量项链

【问题描述】

在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链。在项链上有 NN 颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。因为只有这样,通过吸盘(吸盘是 MarsMars 人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。如果前一颗能量珠的头标记为 mm,尾标记为 rr,后一颗能量珠的头标记为rr ,尾标记为 nn,则聚合后释放的能量为 m×r×nm×r×n(Mars 单位),新产生的珠子的头标记为 mm,尾标记为 nn。
需要时,Mars 人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。
例如:设 N=4N=4,44 颗珠子的头标记与尾标记依次为 (2,3)(3,5)(5,10)(10,2)(2,3)(3,5)(5,10)(10,2)。我们用记号 ⊕⊕ 表示两颗珠子的聚合操作,(j⊕k)(j⊕k) 表示第 j,kj,k 两颗珠子聚合后所释放的能量。则第 4、14、1 两颗珠子聚合后释放的能量为:
(4⊕1)=10×2×3=60
(4⊕1)=10×2×3=60
这一串项链可以得到最优值的一个聚合顺序所释放的总能量为
(((4⊕1)⊕2)⊕3)=10×2×3+10×3×5+10×5×10=710
(((4⊕1)⊕2)⊕3)=10×2×3+10×3×5+10×5×10=710

【输入文件】

输入文件 energy.in 的第一行是一个正整数 NN(4≤N≤1004≤N≤100),表示项链上珠子的个数。第二行是 NN 个用空格隔开的正整数,所有的数均不超过 10001000。第 ii 个数为第 ii 颗珠子的头标记(1≤i≤N1≤i≤N),当 i<Ni<N 时,第 ii 颗珠子的尾标记应该等于第 i+1i+1 颗珠子的头标记。第 NN 颗珠子的尾标记应该等于第 11 颗珠子的头标记。
至于珠子的顺序,你可以这样确定:将项链放到桌面上,不要出现交叉,随意指定第一颗珠子,然后按顺时针方向确定其他珠子的顺序。

【输出文件】

输出文件 energy.out 只有一行,是一个正整数 EE(E≤2.1×109E≤2.1×109),为一个最优聚合顺序所释放的总能量。

【样例 1】

ex_energy1.in

4
2 3 5 10

ex_energy1.ans

710

#include<bits/stdc++.h>
using namespace std;
const int N=520;
long long q,n,head[N],tail[N],f[N][N],da=-1;
int main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
	{
	    scanf("%lld",&head[i]);
	    tail[i-1]=head[i];
	    head[i+n]=head[i];
	    tail[i+n-1]=head[i];
	    tail[2*n]=head[1];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=2*n;j++)
		{
			q=i+j-1;
			if(q>2*n) break;
			for(int k=j;k<q;k++)
				f[j][q]=max(f[j][q],f[j][k]+f[k+1][q]+head[j]*tail[k]*tail[q]);
		}
	}
	for(int i=1;i<=n;i++)
		da=max(da,f[i][i+n-1]);
	printf("%lld",da);
	return 0;
} 

然后老师又找来体育老师给上了体育课就离谱。
到操场上玩“同舟共济”,膝盖疼死了,鞋子里全是石子,虽说过程很快乐。回来之后一口气把语文作业写完了
然后老师一来又赶紧写代码。

环形石子合并

题目描述

将 nn 堆石子绕圆形操场排放,现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分。
请编写一个程序,读入堆数 nn 及每堆的石子数,并进行如下计算:
选择一种合并石子的方案,使得做 n−1n−1 次合并得分总和最大。
选择一种合并石子的方案,使得做 n−1n−1 次合并得分总和最小。

输入格式

输入第一行一个整数 nn,表示有 nn 堆石子。
第二行 nn 个整数,表示每堆石子的数量。

输出格式

输出共两行:
第一行为合并得分总和最小值,
第二行为合并得分总和最大值。

样例

输入样例

4
4 5 9 4

输出样例

43
54

#include <bits/stdc++.h>
using namespace std;
const int N=410;
int n,a[N],f[N][N],g[N][N],s[N],r,maxx,minn;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>s[i];
		s[i+n]=s[i];
	}
	for(int i=1;i<=n*2;i++)	s[i]+=s[i-1];
	memset(f,10,sizeof f);memset(g,-10,sizeof g);
	maxx=-999999;minn=888888;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j+i-1<=2*n;j++)
		{
			r=i+j-1;
			if(i==1)	f[j][r]=g[j][r]=0;
			else
			{
				for(int k=j;k<r;k++)
				{
					f[j][r]=min(f[j][r],f[j][k]+f[k+1][r]+s[r]-s[j-1]);
					g[j][r]=max(g[j][r],g[j][k]+g[k+1][r]+s[r]-s[j-1]);
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		maxx=max(maxx,g[i][i+n-1]);
		minn=min(minn,f[i][i+n-1]);
	}
	cout<<minn<<endl<<maxx;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值