计蒜客习题:蒜头君的蜡笔
题目
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191019191739745.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoaWRvbmdoYW5n,size_16,color_FFFFFF,t_70)
样例
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191019191756792.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoaWRvbmdoYW5n,size_16,color_FFFFFF,t_70)
代码
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const int inf=0x3f3f3f3f;
int n,dp[1<<16+5],f;
bool mp[20][20];
unsigned sum;
const ll mod=4294967296;
ll qpow(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y%2) ans=ans*x%mod;
x=x*x%mod;
y/=2;
}
return ans;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
getchar();
for(int j=1;j<=n;j++)
{
char c;
cin>>c;
mp[i][j]=c-'0';
}
}
memset(dp,inf,sizeof(dp));
dp[0]=0;
for(int i=1;i<(1<<n);i++)
{
f=1;
for(int j=1;j<=n;j++)
{
if(i&(1<<(j-1)))
for(int k=1;k<=n;k++)
if(mp[j][k]&&i&(1<<(k-1)))
{
f=0;
break;
}
if(!f) break;
}
if(f) dp[i]=1;
}
for(int t=1;t<(1<<n);t++)
{
for(int i=t;i;i=(i-1)&t)
dp[t]=min(dp[t],dp[i]+dp[t^i]);
sum+=dp[t]*qpow(233,t)%mod;
}
cout<<sum;
return 0;
}