P1118 [USACO06FEB]數字三角形`Backward Digit Su`…(搜索 + 楊輝三角)

題目鏈接:https://www.luogu.com.cn/problem/P1118

 

思路:

首先根據每個數字出現的次數就是楊輝三角上的值,所以ans = (numi×i)。

然後搜索,最先搜出的ai序列即是結果,然後輸出就好了。

注意減枝,記錄當前出現的編號之和爲tp,當前求出的結果爲sm,1~n之和爲pp,如果pp-tp > sum - sm就不行直接返回。

(楊輝三角太久不用都生疏了,竟然一開始沒想到。)

 

代碼:

#include <bits/stdc++.h>
using namespace std;
const int N = 55;
bool vis[N] = {false};
int a[N][N] = {0},sum,n,pp,b[N];
bool fg = false;
void dfs(int rt,long long sm,int tp)
{
    if(rt == n && sm == sum)
    {
        fg = true;
        for(int i=1;i<=n;i++)
        {
            if(i>1) printf(" "); printf("%d",b[i]);
        }
        return ;
    }
    if(rt == n) return ;
    if(sm >= sum || sum - sm < pp-tp || fg == true) return ; //減枝
    for(int i=1;i<=n;i++)
    {
        if(vis[i] == true) continue;
        vis[i] = true;
        b[rt+1] = i;
        dfs(rt+1,sm+a[n][rt+1]*i,tp+i);
        if(fg == true) return ;
        vis[i] = false;
    }
}
int main(void)
{
    a[1][1] = 1;
    for(int i=2;i<=12;i++)
    {
        for(int j=1;j<=i;j++) a[i][j] = a[i-1][j-1] + a[i-1][j];
    }
    scanf("%d%d",&n,&sum);
    //for(int i=1;i<=n;i++) printf("%d ",a[n][i]); printf("\n");
    pp = 0;
    for(int i=1;i<=n;i++) pp += i;
    dfs(0,0,0);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章