Description
xc抽空光顾了lp的饲养场,在一大堆赞美语之后和lp玩起了一个游戏——
一个完整的倒三角有n层,第一层有n个数字,为原始数字,接下来每层都比上一层减少1个数字,并有f[i,j]=f[i-1,j]+f[i-1,j+1] ,如
3 1 2 4
4 3 6
7 9
16
由xc给出f[n,1],和一个限制max(0<=f[1,i]<=max),lp要迅速回答出字典序最小的f[1]序列,即f[1,1]最小的情况下f[1,2]要最小……以此类推。
xc觉得这个问题对于lp还是太简单了,于是又添加了一些坏点,以坐标的形式给出,所谓坏点就是f[i,j]恒为0,现在就让大家一起来玩这个游戏吧。
一个完整的倒三角有n层,第一层有n个数字,为原始数字,接下来每层都比上一层减少1个数字,并有f[i,j]=f[i-1,j]+f[i-1,j+1] ,如
3 1 2 4
4 3 6
7 9
16
由xc给出f[n,1],和一个限制max(0<=f[1,i]<=max),lp要迅速回答出字典序最小的f[1]序列,即f[1,1]最小的情况下f[1,2]要最小……以此类推。
xc觉得这个问题对于lp还是太简单了,于是又添加了一些坏点,以坐标的形式给出,所谓坏点就是f[i,j]恒为0,现在就让大家一起来玩这个游戏吧。
Input
第一行四个数 n,m,max,f[n,1]
接下来m行,每行一个坐标,表示是一个坏点
接下来m行,每行一个坐标,表示是一个坏点
Output
无解则输出-1
否则输出n行,第i行输出f[1,i],要求f[1]字典序最小
否则输出n行,第i行输出f[1,i],要求f[1]字典序最小
Sample Input
3 1 3 4 2 2
Sample Output
1 3 0
Data Constraint
Hint
【数据说明】
40%的数据:n<=10;m=1;max<=10;f[n,1]<=1,000
90%的数据:max<=100
100%的数据:n<=100;m<=20;max<=10,000;0<=f[n,1]<=10,00
40%的数据:n<=10;m=1;max<=10;f[n,1]<=1,000
90%的数据:max<=100
100%的数据:n<=100;m<=20;max<=10,000;0<=f[n,1]<=10,00
分析
我们把它倒过来,然后就会发现它的系数是杨辉三角
然后这个杨辉三角是有阻挡的
在求出最底一层的系数后,我们可以DFS,然后DFS可以有剪枝:当前格所选的数最大不超过 min(max,剩下的数/当前系数)
#include <iostream> #include <cstdio> #include <memory.h> using namespace std; const int N=1e2+10; int n,m,mx,s,a[N],c[N][N]; bool rtn; void DFS(int dep,int sum) { if (sum==s) { for (int i=dep;i<=n;i++) a[i]=0; rtn=1; return; } if (dep==n+1) return; if (c[n][dep]==0) { a[dep]=0;DFS(dep+1,sum); return; } for (int i=0;i<=min(mx,(s-sum)/c[n][dep]);i++) { a[dep]=i;DFS(dep+1,sum+i*c[n][dep]); if (rtn) return; } } int main() { scanf("%d%d%d%d",&n,&m,&mx,&s); for (int i=1;i<=n;i++) for (int j=1;j<=i;j++) c[i][j]=-1.0; c[1][1]=1; for (int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),c[n-x+1][y]=0; for (int i=2;i<=n;i++) for (int j=1;j<=i;j++) if (c[i][j]==-1.0) c[i][j]=c[i-1][j-1]+c[i-1][j]; DFS(1,0); if (!rtn) { printf("-1"); return 0; } for (int i=1;i<=n;i++) printf("%d\n",a[i]); }