分析
我们把它倒过来,然后就会发现它的系数是杨辉三角
然后这个杨辉三角是有阻挡的
在求出最底一层的系数后,我们可以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 ",a[i]); }