正题
题目大意
一个
n
∗
n
n*n
n∗n的矩阵中
f
i
,
j
=
f
i
−
1
,
j
+
f
i
−
1
,
j
+
1
f_{i,j}=f_{i-1,j}+f_{i-1,j+1}
fi,j=fi−1,j+fi−1,j+1。
但是有格子恒定为0
给出
f
n
,
1
f_{n,1}
fn,1要求在第一列的数字不超过
M
a
x
Max
Max的情况下字典序最小。
求这个字典序。
解题思路
若不考虑坏格子,我们发现
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d
a
+
b
,
b
+
c
,
c
+
d
a+b,b+c,c+d
a+b,b+c,c+d
a
+
2
b
+
c
,
b
+
2
c
+
d
a+2b+c,b+2c+d
a+2b+c,b+2c+d
a
+
3
b
+
3
c
+
d
a+3b+3c+d
a+3b+3c+d
也就是
f
n
,
1
=
∑
i
=
1
n
x
i
f
1
,
i
f_{n,1}=\sum_{i=1}^nx_if_{1,i}
fn,1=i=1∑nxif1,i
那么我们可以计算出每个
x
x
x
f
k
,
i
,
j
f_{k,i,j}
fk,i,j表示
x
k
x_k
xk在
(
i
,
j
)
(i,j)
(i,j)这个位置是多少,那么我们有开始时
f
k
,
1
,
k
=
1
f_{k,1,k}=1
fk,1,k=1
且
f
k
,
i
,
j
=
f
k
,
i
−
1
,
j
+
f
k
,
i
−
1
,
j
+
1
f_{k,i,j}=f_{k,i-1,j}+f_{k,i-1,j+1}
fk,i,j=fk,i−1,j+fk,i−1,j+1
那么最终对于每个
x
i
=
f
k
,
n
,
1
x_i=f_{k,n,1}
xi=fk,n,1
然后就可以 d f s dfs dfs,加上剪枝就可以过掉。
c o d e code code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
int n,m,Big,K,a[N],f[N][N][N];
bool flag,v[N][N];
void dfs(int x,int num)
{
int A=f[x][n][1];
if(x>n&&num==K){
flag=1;
for(int i=1;i<=n;i++)
printf("%d\n",a[i]);
}
if(x>n||num>K||flag) return;
if(A<=0||A>K){
dfs(x+1,num);
return;
}
for(int i=0;i<=Big;i++){
if(num+i*A>K) break;
a[x]=i;
dfs(x+1,num+i*A);
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&Big,&K);
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
v[x][y]=1;
}
for(int i=1;i<=n;i++)
f[i][1][i]=1;
for(int i=2;i<=n;i++)
for(int j=1;j<=n-i+1;j++)
if(!v[i][j]){
for(int k=1;k<=n;k++)
f[k][i][j]=f[k][i-1][j]+f[k][i-1][j+1];
}
dfs(1,0);
if(!flag) printf("-1");
}
/*
100 20 10000 8970
9 79
36 25
16 20
41 44
81 4
18 50
13 55
71 3
18 61
81 20
77 8
7 8
67 2
31 39
47 6
6 22
97 1
3 71
39 39
43 3
*/