给定一个大正方形的边长S,与n个小正方形,第i个小正方形的边长为ai,问能否用这些小正方形,拼成一个大正方形。
n<=16,ai<=10。
#include<cstdio> #include<algorithm> #define N 1001 using namespace std; int n,S,b[11]; bool a[N][N]; void dfs(int now) { if(now==n+1) { bool ok=true; for(int i=1;i<=S && ok;i++) for(int j=1;j<=S && ok;j++) if(!a[i][j]) ok=false; if(ok) { printf("true"); exit(0); } else return; } int x=0,y=0; for(int i=1;i<=S && !x;i++) for(int j=1;j<=S && !y;j++) if(!a[i][j]) x=i,y=j; int R=S; for(int i=y+1;i<=S;i++) if(a[x][i]) { R=i-1; break; } for(int k=1;k<=min(R-y+1,S-x+1);k++) if(b[k]) { b[k]--; for(int i=x;i<x+k;i++) for(int j=y;j<y+k;j++) a[i][j]=true; dfs(now+1); b[k]++; for(int i=x;i<x+k;i++) for(int j=y;j<y+k;j++) a[i][j]=false; } } int main() { scanf("%d%d",&S,&n); int x; for(int i=1;i<=n;i++) scanf("%d",&x),b[x]++; dfs(1); printf("false"); }