洛谷试炼场

P1012 拼数(1s 125Mb)

题目大意

设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数。

例如:n=3时,33个整数13,312,343联接成的最大整数为:34331213

又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613

分析

排序的一个方法,比较相邻两个谁在前谁在后。直接比较字典序显然不可以,我们可以比较a+b和b+a。

代码

bool cmp(string a, string b)
{
	return a+b > b+a;
}

P1094 纪念品分组(1s 125Mb)

题目大意

n个纪念品,每个有一个价值a_i。若两个纪念品价值和小于w则可以和为一组,也可以一个纪念品单独一组,问组数最少是多少。

分析

贪心。对于最大的,如果不能和最小的合成一组则单独成为一组。如果可以和最小的合成一组则合成。

简单证明。加入不和最小的一个合成,若最小的和其他合成,显然交换使最小和最大合成后仍满足答案,因为对于最大的换来一个最小的,对于最大的配对的换来一个比最大小的。think hard。

代码

sort(a+1, a+n+1);
int fr = 1, tl = n, ans = n;
while(fr < tl)
{
	if(a[fr] + a[tl] <= w) fr++, tl--, ans--;
	else tl--;
}

P1080 国王游戏(1s 125Mb)

题目大意

一队人排成一列,每个人有ai和bi。每个人的得分是队列前面的人的ai的乘积除以自己的bi。求任意排列方法下所有人中最大得分最小是多少。

分析

题解十分详细,拜读 https://www.luogu.com.cn/blog/league/solution-p1080


P1902 虫食算 (1s 125Mb)

题目大意

分析1

可能是有点想复杂了,一开始直接暴力40分,就想优化但想偏了可能。我想的是按照最后一位不断往前搜索,写了150多行结果90分。。。

题解里两种思路。搜索的方法是基于每一位上要么(A+B)%n == C 要么 (A+B+1)%n == C,同时最高位不能有进位。还是搜排列,每搜一个字母对整个式子判断,如果字母未被使用不管,如果使用且可以剪枝就停搜。题解作者为了提高剪枝进入的时间,按照从低位到高位字母出现的顺序进行搜索。

不知为何数字从n-1到0搜比从0到n-1快不少。。。

代码1

int ab()
{
	// if(al[a[n]]+al[b[n]] >= n) return 1;
	for(int i = 1; i <= n; i++)
	{
		if(~al[a[i]] && ~al[b[i]] && ~al[c[i]])
		{
			if((al[a[i]]+al[b[i]])%n != al[c[i]]
			&& (al[a[i]]+al[b[i]]+1)%n != al[c[i]]) return 1;
		}
	}
	return 0;
}

void dfs(int x)
{
	if(x == n+1)
	{
		if(check())
		{
			for(int i = 0; i < n; i++) printf("%d ", al[i]);
			exit(0);
		}
		return;
	}
	if(ab()) return;
	for(int i = n-1; i >= 0; i--) if(!vis[i])
	{
		al[lis[x]] = i; vis[i] = 1; // lis为从低位到高位字母出现顺序
		dfs(x+1);
		al[lis[x]] = -1; vis[i] = 0;
	}
}

分析2

看到所谓正解高斯消元。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值