问题描述
逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中。不过他想到了一个游戏来使他更无聊。他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。
输入格式
第一行一个数n,表示n个棍子。第二行n个数,每个数表示一根棍子的长度。
输出格式
一个数,最大的长度。
样例输入
4
1 2 3 1
样例输出
3
数据规模和约定
n<=15
思路与分析
我看到网上很多使用深度优先遍历来解决这道题的,但我觉得没必要,因为C++的标准库提供了更好的、更方便的做法。
使用C++标准库提供的next_permutation方法,能很方便的解决此问题。
#include <iostream>
#include <vector>
#include <algorithm> //使用next_permutation的话,要引入此库
using namespace std;
int n;
int sum;
bool test(vector<int> a)
{
//测试排列a是否符合条件
for(int j=1;j<n;j++)
{
for(int i=1;i<=n-j;i++)
{
a[i]+=a[i+1];
}
}
if(a[1]==sum)
return true;
else
return false;
}
int main()
{
scanf("%d",&n);
scanf("%d",&sum);
vector<int> start_in(n+1,0);
for(int i=1;i<=n;i++)
{
start_in[i]=i;
}
//至此输入数据完毕
do
{
if(test(start_in))
{
//如果该排列符合条件,就输出并跳出循环
for(int i=1;i<=n;i++)
{
printf("%d ",start_in[i]);
}
break;
}
//不符合条件就找下一个排列。
}//使用next_permutation很容易的就找到下一个排列
while(next_permutation(start_in.begin()+1,start_in.end()));
return 0;
}
为了避免大家再去找next_permutation的信息,我放在这里了
next_permutation 函数用于生成给定序列的下一个排列组合,即字典序中比当前排列大的下一个最小排列。如果当前排列已经是最大排列,则 next_permutation 会将序列重新排列为最小排列,并返回 false。否则,它会返回 true。
prev_permutation 函数则相反,用于生成给定序列的前一个排列组合,即字典序中比当前排列小的前一个最大排列。
函数原型如下:
bool next_permutation (BidirectionalIterator first, BidirectionalIterator last);
其中,first 和 last 是指向序列起始和结束的位置的迭代器。
对此,感兴趣的话,可以参考:
https://blog.csdn.net/qq_71654538/article/details/128366528#comments_31010784