这个题我们乍一看会有些熟悉。觉得是可以用DP来做的那个题。但是打眼一看,就会发现不对了。因为那个题是顺推而这个题则是逆推。
这样的话可怎么办呢。
我们可以在草稿纸上推一下,我们随便写个数n。
再标个a,b,c,d。
当n=4时
我们可以得到下面的式子
sum=a+3b+3c+d
a+2b+c b+2c+d
a+b b+c c+d
a b c d
因此我们就可以想到杨辉三角了。
扫描二维码关注公众号,回复:
1720066 查看本文章
我们设yh数组为杨辉三角。
我们先预处理出杨辉三角的值,也是主函数。
int main() { cin>>n>>sum; yh[1][1]=1; for(int i=2;i<=n;i++) for(int j=1;j<=i;j++) yh[i][j]=yh[i-1][j-1]+yh[i-1][j]; dfs(1,0); return 0; }
再进行搜索
搜索函数:即为dfs(step,sum)
step指现在要选了第几个数了,sum指现在选的数的和。
接下来我们就来写dfs。
我们可以加两个判断是否退出。
一个是判断方案是否已经被输出了。
一个是当前的值是否比sum大。
因为总共有n个数且这n个数是一个从1到n的排列。
所以我们可以从1到n枚举,如果这个数没有被使用,sum加上该数乘杨辉三角所得的值。
然后使用上面的两个判断,如果并没有退出就继续,直到退出或找到结果。
代码:
#include<iostream> using namespace std; int n,sum,yh[20][20],a[14]; bool flag,vis[14]; void dfs(int step,int s) { if(flag) return; if(s>sum) return; if(step==n+1) { if(s==sum) { for(int i=1;i<=n;i++) cout<<a[i]<<' '; flag=true; } return; } for(int i=1;i<=n;i++) if(!vis[i]) { a[step]=i; s+=yh[n][step]*a[step]; vis[i]=true; dfs(step+1,s); vis[i]=false; s-=yh[n][step]*a[step]; } } int main() { cin>>n>>sum; yh[1][1]=1; for(int i=2;i<=n;i++) for(int j=1;j<=i;j++) yh[i][j]=yh[i-1][j-1]+yh[i-1][j]; dfs(1,0); return 0; }