P1118 [USACO06FEB]數字三角形Backward Digit Su…
P1118 [USACO06FEB]數字三角形Backward Digit Su…
題目描述
FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this:
3 1 2 4
4 3 6
7 9
16
Behind FJ‘s back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ‘s mental arithmetic capabilities.
Write a program to help FJ play the game and keep up with the cows.
有這麽一個遊戲:
寫出一個1~N的排列a[i],然後每次將相鄰兩個數相加,構成新的序列,再對新序列進行這樣的操作,顯然每次構成的序列都比上一次的序列長度少1,直到只剩下一個數字位置。下面是一個例子:
3 1 2 4
4 3 6
7 9 16 最後得到16這樣一個數字。
現在想要倒著玩這樣一個遊戲,如果知道N,知道最後得到的數字的大小sum,請你求出最初序列a[i],為1~N的一個排列。若答案有多種可能,則輸出字典序最小的那一個。
[color=red]管理員註:本題描述有誤,這裏字典序指的是1,2,3,4,5,6,7,8,9,10,11,12
而不是1,10,11,12,2,3,4,5,6,7,8,9[/color]
輸入輸出格式
輸入格式:
兩個正整數n,sum。
輸出格式:
輸出包括1行,為字典序最小的那個答案。
當無解的時候,請什麽也不輸出。(好奇葩啊)
輸入輸出樣例
輸入樣例#1:
4 16
輸出樣例#1:3 1 2 4
說明
對於40%的數據,n≤7;
對於80%的數據,n≤10;
對於100%的數據,n≤12,sum≤12345。
對於字典序最小的 排列 有一個神奇的性質
對於這個排列 A1 A2 ....An
我們可以發現 A1*C(n-1,0)+A2*C(n-1,1)+....+An*C(n-1,n-1)==sum // sum即為題目中給的和
看樣例 3*1+1*3+2*3+1*4==16
數據n<=12 所以我們可以DFS枚舉全排列 進行判斷
當然 還要加個剪枝
1 #include <cctype> 2 #include <cstdio> 3 #include <cstdlib> 4 5 const int MAXN=110; 6 7 int n,sum; 8 9 int C[MAXN][MAXN],ans[MAXN]; 10 11 bool vis[MAXN]; 12 13 inline void read(int&x) { 14 int f=1;register char c=getchar(); 15 for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar()); 16 for(;isdigit(c);x=x*10+c-48,c=getchar()); 17 x=x*f; 18 } 19 20 inline void DFS(int num,int tot) { 21 if(tot>sum) return; 22 if(num>n) { 23 if(sum==tot) { 24 for(int i=1;i<=n;++i) printf("%d ",ans[i]); 25 exit(0); 26 } 27 } 28 for(int i=1;i<=n;++i) { 29 if(!vis[i]) { 30 vis[i]=true; 31 ans[num]=i; 32 DFS(num+1,tot+C[n][num]*i); 33 vis[i]=false; 34 } 35 } 36 37 } 38 39 int hh() { 40 read(n);read(sum); 41 C[0][0]=1; 42 for(int i=1;i<=n;++i) 43 for(int j=1;j<=i;++j) 44 C[i][j]=C[i-1][j-1]+C[i-1][j]; 45 DFS(1,0); 46 return 0; 47 } 48 49 int sb=hh(); 50 int main(int argc,char**argv) {;}代碼
P1118 [USACO06FEB]數字三角形Backward Digit Su…