状态压缩枚举
注意n*n == k 的情况
class Solution {
public:
int a[7][7];
int paintingPlan(int n, int k) {
int nm=0;
if(k==n*n||k==0)return 1;
for(int sta=0;sta < ( 1 << (2 * n) );sta++){
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
if((sta >> i) & 1){
for(int j=0;j<n;j++){
a[i][j]=1;
}
}
}
for(int i=n;i<2*n;i++){
if((sta >> i) & 1){
for(int j=0;j<n;j++){
a[j][i-n]=1;
}
}
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(a[i][j])ans++;
}
if(ans==k){
// cout<<sta<<" "<<ans<<endl;
nm++;
}
}
return nm;
}
};
数学公式
枚举行列画了几道,就可求出涂色格子数。
然后组合数搞一搞即可
class Solution {
public:
int C(int n,int m){
int ans=1;
for(int i=1;i<=n;i++)ans*=i;
for(int i=1;i<=m;i++)ans/=i;
for(int i=1;i<=n-m;i++)ans/=i;
return ans;
}
int paintingPlan(int n, int k) {
int nm=0;
if(k==n*n||k==0)return 1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(i * n + j * (n-i) == k){
nm += C(n,i) * C(n,j);
// cout<<i<<" "<<j<<" "<<C(n,i)<<endl;
}
}
return nm;
}
};