一种积木搭建方式,高为H的积木,最底层有M个积木,每一层的积木数是他的低一层的积木数+1或-1。总共有N个积木。(且每行积木数不超过10)
1.JPG
比如上图N=13 H=6 M=2。
输入格式:
第一行为三个整数、N、H、M。
第二行以后每行一个整数K,-1为结束符。
输出格式:
第一行为满足N、H、M的积木搭建方案总数(1<=N<=540 H<=60 M<=10)
以后每一行对于对应的K,给出顺序排列的第K种方案(最小的排列为第一种)。
样例输入:
13 6 2
1
3
-1
样例输出:
3
2 1 2 3 2 3
2 3 2 3 2 1
时间限制:
1000
空间限制:
262144
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,h;
long long k;
long long dp[61][11][541];
int ans[10001];
int main()
{
cin>>n>>h>>m;
for(int i=1;i<=min(m+h-1,10);i++) dp[1][i][i]=1;
for(int hh=2;hh<=h;hh++)
for(int mm=1;mm<=min(m+h-1,10);mm++)
for(int nn=mm;nn<=n;nn++)
{
dp[hh][mm][nn]=dp[hh-1][mm-1][nn-mm]+dp[hh-1][mm+1][nn-mm];
}
cout<<dp[h][m][n]<<endl;
while(1)
{
cin>>k;
if(k==-1) break;
int hh=h,mm=min(10,m),nn=n;
while(1)
{
ans[hh]=mm;
if(hh==1) break;
hh--;nn-=mm;
long long xx=dp[hh][mm-1][nn];
if(k<=xx)
{
mm--;
}
else{
mm++;k-=xx;
}
}
cout<<ans[h];
for(int i=h-1;i>=1;i--) cout<<" "<<ans[i];
cout<<endl;
}
}
这道题就是先dp再二分答案,然后就这么A了。