P1118 [USACO06FEB]Backward Digit Sums G/S

题解:
  (1)暴力法。对1~N这N个数做从小到大的全排列,对每个全排列进行三角形的计算,判断是否等于N。
  对每个排列进行三角形计算,需要O(N2)次。例如第1行有5个数{a,b,c,d,e},那么第2行计算4次,第3行计算3次…等等,总次数是O(N2)的。
  a    b    c    d    e
    a+b    b+c   c+d   d+e
      a+2b+c b+2c+d c+2d+e
       a+3b+3c+d b+3c+3d+e
          a+4b+6c+4d+e
  共有N!=4亿个排列,总复杂度是O ( N ! N 2 ) 的,显然会超时。
  2)三角计算优化+剪枝。
  1)三角计算的优化。对排列进行三角形计算,并不需要按部就班地算,比如{a,b,c,d,e}这5个数,直接算最后一行的公式a+4b+6c+4d+e就好了,复杂度是O(N)的。

不同的N有不同的系数,比如5个数的系数是{1,4,6,4,1},提前算出所有N的系数备用。可以发现,这些系数正好是杨辉三角。
  2)剪枝。即使有了杨辉三角的优化,总复杂度还是有O(N!N),所以必须进行最优性剪枝。对某个排列求三角形和时,如果前面几个元素和已经大于sum,

那么后面的元素就不用再算了。例如,N=9时,计算到排列{2,1,3,4,5,6,7,8,9},如果前5个元素{2,1,3,4,5}求和已经大于sum,那么后面的{6,7,8,9}~{9,8,7,6}都可以跳过,

下一个排序从{2,1,3,4,6,5,7,8,9}开始。本题sum≤12345,和不大,用这个简单的剪枝方法可以通过。
  3)可以用DFS求全排列,也可以直接用STL 的next_permutation()求全排列。

#include <cstdio>
using namespace std; int n,sum;
//以下所有数组的大小都比所需值稍大,是为了防止越界
int visited[25]={0}; //防止重复选数,这是 dfs 枚举排列的要点
int ans[25]; //放置答案
int pc[25];//构造所有i C n-1 int dfs(int i,int num,int v); //写函数原型是(我的)好习惯! int main(void){
scanf("%d%d",&n,&sum);
//下面构造杨辉三角(即组合数表)
pc[0]=pc[n-1]=1; //杨辉三角性质,两边都是1
if (n>1)
for (int i=1;i*2<n;i++)
pc[i]=pc[n-1-i]=(n-i)*pc[i-1]/i; //利用杨辉三角对称性和组合数公式计算
//下面枚举计算
if (dfs(0,0,0)) //0 仅起占位符作用
for (int i=1;i<=n;i++)
printf("%d ",ans[i]); //输出答案
return 0;
} int dfs(int i,int num,int v){
//参数说明:i 表示已经枚举了前 i 个数(数的序号从 1 开始),num 表示第 i 个数是 num,v 表示前 i 个数的“和”为 v
//返回值说明:返回 0 表示不行(不可能),返回 1 表示找到了可行解。利用返回值就可以在找到第一个解后直接返回了
if (v>sum) //“剪枝”,及时排除不可能情况,加速枚举
return 0; //不可能
if (i==n){ //已经枚举了前 n 个(全部),判断一下是否是可行解
if (v==sum){
ans[i]=num; //放置解
return 1;
}
else
return 0;
}
visited[num]=1; //标记一下“第 i 个数的值已经使用过了”
//下面寻找第 i+1 个数
for (int j=1;j<=n;j++){
if (!visited[j] && dfs(i+1,j,v+pc[i]*j)){ //v+pc[i]*j表示前(i+1)个数的“和”
//注意,如果数的序号从 1 开始,那么第 i 个数的系数实际上是 (i-1) C (n-1)
//执行到这里表示已经找到了可行的解
ans[i]=num;
return 1;
}
}
visited[num]=0; //如果没有找到,一定记得复位,为进一步的寻找做准备
return 0; //执行到这里一定是没有找到解
}

P1118 [USACO06FEB]Backward Digit Sums G/S的更多相关文章

  1. BZOJ1653: [Usaco2006 Feb]Backward Digit Sums

    1653: [Usaco2006 Feb]Backward Digit Sums Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 207  Solved:  ...

  2. Backward Digit Sums(POJ 3187)

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5495   Accepted: 31 ...

  3. Backward Digit Sums(暴力)

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5664   Accepted: 32 ...

  4. 1653: [Usaco2006 Feb]Backward Digit Sums

    1653: [Usaco2006 Feb]Backward Digit Sums Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 285  Solved:  ...

  5. POJ3187 Backward Digit Sums 【暴搜】

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4487   Accepted: 25 ...

  6. POJ 3187 Backward Digit Sums 枚举水~

    POJ 3187  Backward Digit Sums http://poj.org/problem?id=3187 题目大意: 给你一个原始的数字序列: 3   1   2   4  他可以相邻 ...

  7. 【POJ - 3187】Backward Digit Sums(搜索)

    -->Backward Digit Sums 直接写中文了 Descriptions: FJ 和 他的奶牛们在玩一个心理游戏.他们以某种方式写下1至N的数字(1<=N<=10). 然 ...

  8. Luogu P1118 [USACO06FEB]数字三角形 Backward Digit Sums | 搜索、数学

    题目链接 思路:设一开始的n个数为a1.a2.a3...an,一步一步合并就可以用a1..an表示出最后剩下来的数,不难发现其中a1..an的系数恰好就是第n层杨辉三角中的数.所以我们可以先处理出第n ...

  9. (DFS、全排列)POJ-3187 Backward Digit Sums

    题目地址 简要题意: 输入两个数n和m,分别表示给你1--n这些整数,将他们按一定顺序摆成一行,按照杨辉三角的计算方式进行求和,求使他们求到最后时结果等于m的排列中字典序最小的一种. 思路分析: 不难 ...

随机推荐

  1. 七夕特别篇|用Python绘画牛郎织女在鹊桥相见

    大家好,我是辰哥~ 今天就是七夕节,首先提前祝福有伴侣的小伙伴,七夕快乐,没有伴侣的小伙伴,今天就会找到伴侣,(给看到这句话的你好运加持,哈哈哈). 作为会Python的我们必须做点好玩且有意义的东西 ...

  2. 浅谈Java迭代器

    迭代器Iterator 概述: 迭代器(Iterator):它不是一个容器,它是一种用于访问容器的方法,可用于迭代 List.Set和Map等容器. 迭代:一个一个的往外拿. 作用:帮我们遍历或者拿到 ...

  3. 熬夜肝了一份 C++/Linux 开发学习路线

    大家好,我是帅地. 之前写过几篇学习路线的文章 前端开发学习路线 Java 后端开发学习路线 一般开发岗主流的就是 Java 后台开发,前端开发以及 C++ 后台开发,现在 Go 开发也是越来越多了, ...

  4. MySQL-07-information_schema/show

    information_schema.tables视图 DESC information_schema.TABLES /** TABLE_SCHEMA ---->库名 TABLE_NAME -- ...

  5. Python语言系列-09-socket编程

    简介 软件开发的架构 1.C/S架构(client-server) 2.B/S架构 (browser-server) 网络基础概念 网络三要素: 1.ip 2.port 3.通信协议:TCP.UDP ...

  6. innodb是如何存数据的?yyds

    前言 如果你使用过mysql数据库,对它的存储引擎:innodb,一定不会感到陌生. 众所周知,在mysql8以前,默认的存储引擎是:myslam.但mysql8之后,默认的存储引擎已经变成了:inn ...

  7. Git进行clone的时候,报错:remote: HTTP Basic: Access denied fatal: Authentication failed for ...

    先执行: git config --system --unset credential.helper 原因:用户名或者密码错: 会提示让重新输入用户名和密码,输入正确的用户名和密码即可! 这样以后发现 ...

  8. VMware上安装的Ubuntu不显示全屏解决方法

    花费了好一会才把电脑上的Vmware装上,把Ubuntu装到虚拟机上,谁知道Ubuntu不显示全屏,我调了分辨率,奈何Ubuntu里面固定的分辨率没有跟我电脑匹配的,然后开始寻找解决方法,在网上找了很 ...

  9. 第一次上传代码到gitee

    初始化 git init 添加文件到本地仓库 git add . 提交文件到本地仓库 git remote add origin 仓库地址 拉去远程仓库代码 git pull origin maste ...

  10. k8s 执行 ingress yaml 文件报错: error when creating "ingress-myapp.yaml": Internal error occurred: failed calling webhook

    k8s 执行 ingress yaml 文件报错:错误如下: [root@k8s-master01 baremetal]# kubectl apply -f ingress-test.yaml Err ...