洛谷Oj-[USACO06FEB]数字三角形-数学 + 剪枝
2017-08-28 17:29
381 查看
问题描述:
有这么一个游戏:
写出一个1~N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置。下面是一个例子:
3 1 2 4
4 3 6
7 9
16
最后得到16这样一个数字。
现在想要倒着玩这样一个游戏,如果知道N,知道最后得到的数字的大小sum,请你求出最初序列a[i],为1~N的一个排列。若答案有多种可能,则输出字典序最小的那一个。
AC代码:
解决方法:
当看到最终的数是由一步步加上去的时,想到最终的数中每个数加的次数一定有规律,于是就从n为3,4,5在草稿纸上手推,当得到1 4 6 4 1这组数时,发现这是组合数。最初的想法是暴力,从最小的字典序开始,运用规律,一次次去尝试,结果T了4个点,有点绝望。虽然是在搜索的栏目里,但是我这个写法并不是搜索,剪枝也没有思路。看了题解后发现我还是太naive了。方法可以说是广义上的剪枝吧,加上a[i]后,ans的大小超过了sum,继续累加也一定不会得到答案。由于杨辉三角中间的数大,所以想把a[i]到a
由大到小排列一下,这样下一次重排就将一定不符合题意的那若干种排列跳过。
改天再写个搜索的。
有这么一个游戏:
写出一个1~N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置。下面是一个例子:
3 1 2 4
4 3 6
7 9
16
最后得到16这样一个数字。
现在想要倒着玩这样一个游戏,如果知道N,知道最后得到的数字的大小sum,请你求出最初序列a[i],为1~N的一个排列。若答案有多种可能,则输出字典序最小的那一个。
AC代码:
int a[20],fact[12] = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};//将0到11的阶乘打表 int c(int n,int m)//计算组合数 { return fact / (fact[m] * fact[n - m]);//公式 } bool cmp(const int &a,const int &b)//自定义比较函数 { return a > b; } int main() { int n,sum,ans; cin >> n >> sum;//输入 for(int i = 1; i <= n; ++i)//从字典序最小开始。1,2,......,n a[i] = i; while(true) { ans = 0;//重置 for(int i = 1; i <= n; i++) { ans += c(n - 1,i - 1) * a[i];//计算最终得到的数字 if(ans > sum)//可行性剪枝 sort(a + i,a + n + 1,cmp);//将a[i...n]降序排列 } if(ans == sum)//如果找到了答案 { for(int i = 1; i <= n; i++)//打印 printf("%d ",a[i]); break; } if(next_permutation(a + 1,a + n + 1) == false)//如果已经是最后一个排列了 break;//无解,跳出循环 } printf("\n"); return 0; }
解决方法:
当看到最终的数是由一步步加上去的时,想到最终的数中每个数加的次数一定有规律,于是就从n为3,4,5在草稿纸上手推,当得到1 4 6 4 1这组数时,发现这是组合数。最初的想法是暴力,从最小的字典序开始,运用规律,一次次去尝试,结果T了4个点,有点绝望。虽然是在搜索的栏目里,但是我这个写法并不是搜索,剪枝也没有思路。看了题解后发现我还是太naive了。方法可以说是广义上的剪枝吧,加上a[i]后,ans的大小超过了sum,继续累加也一定不会得到答案。由于杨辉三角中间的数大,所以想把a[i]到a
由大到小排列一下,这样下一次重排就将一定不符合题意的那若干种排列跳过。
改天再写个搜索的。
相关文章推荐
- [USACO06FEB]数字三角形
- 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…
- P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 杨辉三角 [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷—— P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 1354 选数字 DP背包 + 数学剪枝
- 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷Oj-数字三角形-动态规划
- 洛谷 P1118 [USACO06FEB] 数字三角形Backward Digit Su…
- P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 【搜索】洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Sums
- 洛谷P1118 [USACO06FEB]数字三角形Backward Digit Su…
- [USACO06FEB]数字三角形Backward Digit Su…
- 洛谷P1118 [USACO06FEB]数字三角形Backward Digit Su…
- P1118 [USACO06FEB]数字三角形Backward Digit Su…
- |洛谷|DFS|P1118 [USACO06FEB]数字三角形Backward Digit Su…
- 动态规划解决数字塔-数字三角形问题