2021/2/17模拟赛

T1音量调节

在这里插入图片描述
一看这数据范围,不就dfs么。

#include <bits/stdc++.h>
using namespace std;
int a[6666],n,beg,maxx,ans=-1;
bool flag[601][1110];
void dfs(int x,int y)//x记录音量,y记录唱到第几首
{
    
    
	if(flag[y][x]==1)//如果该状态出现过,就return
	{
    
    
		return ;
	}
	flag[y][x]=1;//记录这个状态
	if(x>maxx)//音量过高就return
		return ;
	if(x<0)//音量过低就return
		return ;
	if(y>n)//如果活着唱完
	{
    
    
		ans=max(ans,x);//记录是不是最高音
		return ;
	}
	dfs(x+a[y],y+1);//音量增加a[y]
	dfs(x-a[y],y+1);//减少
	return ;
}
int main()
{
    
    
	cin>>n>>beg>>maxx;//输入唱几首歌开始音量和最高音量
	for(int i=1;i<=n;i++)
		cin>>a[i];
	dfs(beg,1);//初始音量和第一首歌
	cout<<ans;
	return 0;
}

勉强算个记忆化搜索吧,一开始没定义flag,后来发现可以依据DP应有的“不重不漏”,记录每次唱到第几首的时候音量多少,极大避免重复现象,而dfs本身就不容易漏。
交的时候没注意把

	if(flag[y][x]==1)//如果该状态出现过,就return
	{
    
    
		return ;
	}
	flag[y][x]=1;//记录这个状态

写成了

	if(flag[x][y]==1)//如果该状态出现过,就return
	{
    
    
		return ;
	}
	flag[x][y]=1;//记录这个状态

导致数组越界,只有10分。
该出来后只有50分,看了看错误又看了看题,发现是题看错了
在这里插入图片描述

看成了过程中的最大音量,就离谱,这还50分
在这里插入图片描述
改完之后成了现在这副模样,终于愉快地AC了。
更离谱的是在洛谷中可以看到
在这里插入图片描述
河南省选难度普及-

T2

看了之后发现是状压DP,但第一时间没思路直接跳了

T3 补兵

题目大意

在玩刀塔的时候队友老鹿抢你兵线,你玩幽鬼,你先攻击,每次能打一个小兵一滴血,而老鹿让所有小兵减少一滴血,问你能补到多少兵。
我玩游戏的时候还补不到兵呢写个这就能补到了???
还是没有正解思路,于是想打个暴力,记录血量为i的小兵个数,如果个数大于2且i大于3,则打一下这个小兵,让小兵的血量尽可能错开,不过首先要把血量为1的小兵先打掉。

#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int zuida,t,b[N],a,n,ans;
void init()//输入数据
{
    
    
	ans=0;
	memset(b,0,sizeof b);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a;
		b[a]++;
		zuida=max(zuida,a);
	}
}
void work(int x)//看补兵,x记录血量最多的兵的血量
{
    
    
	if(x<=0)//都死了
	{
    
    
		return ;
	}
	if(b[1])//如果有小兵血量为1
	{
    
    
		ans++;//为答案贡献1
		for(int i=1;i<=x;i++)//老鹿AOE小兵每个减少1滴血
		{
    
    
			b[i]=b[i+1];
		}
		x--;//最大的血量比原来少1
		work(x);
		return ;
	}
	for(int i=3;i<=x;i++)//想办法让小兵血量错开
	{
    
    
		if(b[i]>1)
		{
    
    
			b[i]--;
			b[i-1]++;
		}
	}
	for(int i=1;i<=x;i++)
	{
    
    
		b[i]=b[i+1];
	}
	x--;
	work(x);
	return ;	
}
int main()
{
    
    
	cin>>t;
	while(t--)
	{
    
    
		init();
		work(zuida);
		cout<<ans<<endl;
	}
	return 0;
}

写的时候感觉做过一道类似的题但死活想不出来,最后骗了10分,这个比赛里算是没有更高的了……

正解思路

在这里插入图片描述

T4 CF111C Petya and Spiders

又双叒叕是状压DP,但是在老师给的PDF中可见
在这里插入图片描述
只水个50%的分我觉得就很棒
于是在纸上写写画画,感觉三个连一起,左右两个都移动到中间格子的话收益最大。

#include <bits/stdc++.h>
using namespace std;
int a,b,m,n,ans;
void work1()
{
    
    
	a=m/3;
	b=m%3;
	if(b==0)
	{
    
    
		ans+=2*a;
	}
	if(b==1)
	{
    
    
		ans+=2*a;
	}
	if(b==2)
	{
    
    
		ans+=a*2;
		ans+=1;
	}
}
void work2()
{
    
    
	a=m/3;
	b=m%3;
	if(b==0)
	{
    
    
		ans+=(m/3)*2*n;
	}
	if(b==1)
	{
    
    
		ans+=(m/3)*2*n;
		ans+=1;
	}
	if(b==2)
	{
    
    
		ans+=a*2*n;
		ans+=2;
	}
}
void workn3()
{
    
    
	a=n/3;
	ans+=m*2*a;
}
void workm3()
{
    
    
	a=m/3;
	ans+=2*n*a;
}
void work()
{
    
    
	a=n/3;
	b=n%3;
	ans+=m*2*a;
	m=b;
	if(n==1) work1();
	else if(n==2) work2();
}
int main()
{
    
    
	cin>>n>>m;
	if(m<n)
		swap(m,n);
	int rp;
	rp++;
	if(n%3==0)	workn3();
	else if(m%3==0)	workm3();
	else if(n==1) work1();
	else if(n==2) work2();
	else work();
	cout<<ans;
	return 0;
}

分段写了一下,最后感觉把大数据拆开写说不定能AC掉于是写了work(),于是高高兴兴拿了30,成绩出来后也确实没人得50,经老师提点,有一个更好的方法水,保证n是m,n中较小的数,而由m*n≤40可得,此时的n最大是6,6×6=36,数据还一定是整数,按照这个思路的话数也应该数很多分。

T5 奶牛大聚会

题目描述

Bessie 正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。

每个奶牛居住在 N 个农场中的一个,这些农场由N−1 条道路连接,并且从任意一个农场都能够到达另外一个农场。道路 i 连接农场 Ai 和 Bi,长度为Li。集会可以在 N 个农场中的任意一个举行。另外,每个牛棚中居住着 Ci 只奶牛。

在选择集会的地点的时候,Bessie 希望最大化方便的程度(也就是最小化不方便程度)。比如选择第 X 个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和(比如,农场 ii到达农场 X 的距离是 20,那么总路程就是 Ci×20)。帮助 Bessie 找出最方便的地点来举行大集会。

输入格式

第一行一个整数 N 。

第二到 N+1 行:第 i+1 行有一个整数 Ci。

第 N+2 行到 2N 行:第i+N+1 行为 3 个整数:Ai,Bi 和 Li。

输出格式

一行一个整数,表示最小的不方便值。

分析过程:

1.首先这是USACO 的题
2.感觉是树形DP
3.Floyd能不能水
4.快到时间了,检查下其他的有没有什么问题吧


于是垫了个底

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ydsrwex/article/details/113833882