今天做了场srm,500pt想到了是dp但是无从下手,但是看了rng_58的神代码后顿觉海阔天空啊(盯着看了一个下午),相比于一年前的写法,真的是不忍直视啊,
TC真是个好地方。。。赞!
其实就是将普通的铺砖块问题用类似于插头dp逐格递推的思路来写。下面的代码相信大家应该都能看懂。
#include#include #include long long dp[2][1<<11]; int main() { int n , m; while(scanf("%d%d",&n,&m),n||m) { int cur = 0 , nxt = 1; dp[cur][0] = 1; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { memset(dp[nxt],0,sizeof(dp[nxt])); for(int s = 0; s < (1< >1] += dp[cur][s];continue;} if(j+1 > 1; dp[nxt][mask] += dp[cur][s]; } if(i+1 > 1; dp[nxt][mask] += dp[cur][s]; } } std::swap(cur,nxt); } } printf("%I64d\n",dp[cur][0]); } return 0; } #include #include #include long long dp[2][1<<11]; int main() { int n , m; while(scanf("%d%d",&n,&m),n||m) { int cur = 0 , nxt = 1; dp[cur][0] = 1; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { memset(dp[nxt],0,sizeof(dp[nxt])); for(int s = 0; s < (1< >1] += dp[cur][s];continue;} if(j+1 > 1; dp[nxt][mask] += dp[cur][s]; } if(i+1 > 1; dp[nxt][mask] += dp[cur][s]; } } std::swap(cur,nxt); } } printf("%I64d\n",dp[cur][0]); } return 0; }
下面是一年前的写法。。。
#include#include int h,w; __int64 dp[15][2050]; void dfs1(int row,int state,int col,int state2){ if(col>w) return ; if(col==w) { dp[row+1][state2]+=dp[row][state]; return ; } if(!(state&(1< w) return ; if(col==w) { if(state2!=state) dp[row][state2]+=dp[row][state]; return ; } if(!(state&(1< =0;j--) if(dp[i+1][j]) dfs2(i+1,j,0,j); } } int main(){ while(scanf("%d%d",&h,&w)!=EOF && h+w){ int temp; if(h