标签:des style blog http color os io for

2 2 0 0 0 0 3 3 0 0 0 0 2 1 0 0 0
24 2140
题目大意:
解题思路:给一张图,问你解锁屏幕的方案数,0 表示按键,当被触摸过可以跳过,1表示不能被跳过,2表示可以被跳过。
问你按键的方法数?
解题代码:用“ 0 1 ” 的二进制 表示0号按键的状态。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
int a[10][10],n,m,vsize,pos[10][10];
ll dp[20][(1<<16)];
vector <pair<int,int> > v;
void input(){
v.clear();
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[i][j]);
if(a[i][j]==0){
v.push_back(make_pair(i,j));
pos[i][j]=v.size()-1;
}
}
}
vsize=v.size();
}
int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
bool canJump(int sum,int s,int d){
int len=gcd( abs(v[s].first-v[d].first),abs(v[s].second-v[d].second) ) ;
int offx=(v[d].first-v[s].first)/len,offy=(v[d].second-v[s].second)/len;
for(int i=1;i<=len-1;i++){
int x=v[s].first+offx*i,y=v[s].second+offy*i;
if(a[x][y]==1) return false;
else if(a[x][y]==0){
if( ( sum&(1<<pos[x][y]) ) ==0 ) return false;
}
}
return true;
}
ll DP(int s,int sum){
if( sum==(1<<vsize)-1 ) return 1;
if(dp[s][sum]!=-1) return dp[s][sum];
ll ret=0;
for(int i=0;i<vsize;i++){
if( sum&(1<<i) ) continue;
if( canJump(sum,s,i) ){
ret+=DP(i,sum+(1<<i));
}
}
return dp[s][sum]=ret;
}
void solve(){
ll ans=0;
for(int i=0;i<vsize;i++){
ans+=DP(i,(1<<i));
}
printf("%I64d\n",ans);
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
input();
solve();
}
return 0;
}
HDU 4026 Unlock the Cell Phone(动态规划),布布扣,bubuko.com
HDU 4026 Unlock the Cell Phone(动态规划)
标签:des style blog http color os io for
原文地址:http://blog.csdn.net/a1061747415/article/details/38516825