【p1118】洛谷P1118数字三角形题解

这个题我们乍一看会有些熟悉。觉得是可以用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

因此我们就可以想到杨辉三角了。

我们设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; 
}

猜你喜欢

转载自www.cnblogs.com/liuwenyao/p/9216824.html