sgu225 装压DP&位运算
来源:互联网 发布:js selected选中事件 编辑:程序博客网 时间:2024/05/20 23:07
题意是:给出一个 n*n 的棋盘 ,问放置 k 的 骑士 相当于 象棋中的马 有多少中放置方法。。。
n等于10 是TLE ,于是 n=10 打表
用 dfs写的 ,运行时间长,但代码简单。。
开数组时 用到滚动数组。。。
由于攻击范围是 两行 ,所以 是在三行之间做DP ,每种状态表示两行 ,这样上下三行之间的关系就两种状态直接的关系。。
相当于 f[ i ] [ j ] = opt(f[ j ][ t ]);
此题由于两行之间会攻击, 所以两行状态 合成一中状态时 (就是用最长二十位 的数来表示两行状态,10 位 表示 一行),合法的状态数 就会减少。。 可以预处理出所有合法状态。。。。
#include <cstdio>#include <cstring>#include <iostream>#define LL long long using namespace std;// 打表LL mark[110]={1,100,4662,135040,2732909,41199404,481719518,4491423916,34075586550,213628255072,1120204619108,4961681221524,18715619717199,60541371615660,168976761361446,409191804533576,864172675710439,1599730843649564,2609262108838924,3770687313420780,4857550050070531,5616928666465104,5874943705896600,5604501518609804,4917655076255841,3999855946779732,3034690618677388,2156485957257040,1437827591264317,899278231344296,526753407546620,288274613750624,146990556682887,69626509814580,30542906352994,12366448408056,4604442057431,1569983914256,487876545370,137395261280,34831261750,7884855000,1578162590,275861904,41455966,5246412,543534,44244,2652,104,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};int state[30000]; //存取合法状态。。。。int fstate[(1<<20)+1000];int statenum =0 ;LL f[2][29000][52];int n,k;int bitnum(int i ){int sum =0;while(i!=0){ int t = i&(-i); sum++; i-=t;}return sum ;}void init_state(){statenum =0; int line1 ; int line2 ; for(int i=0 ;i<1<<(2*n);i++){ line2 = i>>n; line1 = line2 << n; line1 = i - line1; if(line2&(line1<<2)){ continue; } if(line2&(line1>>2)){ continue; } statenum ++; state[statenum]= i; fstate[i] =statenum; }}int maxidx []={0,1,5,6,9,14,18,26,32,42,51};void dfs(int r , int i,int j, int lev,int num){ int line1 = j>>n; int line2 = line1<<n; line2 = j -line2; if(lev==n){ for(int t =num;t<=maxidx[n];t++){ int tmp = (line2<<n)+i; f[r%2][fstate[tmp]][t] +=f[(r+1)%2][fstate[j]][t-num]; }return ; } int st = (line1>>1)|(line1<<1)|(line2>>2)|(line2<<2); dfs(r,i,j,lev+1,num); if(!(st&(1<<lev))){ dfs(r,i|(1<<lev),j,lev+1,num+1); }}void solve (){if(n==10){ cout << mark[k]<<endl; return ;}if(k>maxidx[n]){ cout << 0<<endl;; return ;} init_state(); memset(f,0,sizeof(f)); for(int i=1;i<=statenum;i++){ if(i>(1<<n)){ break; } f[1][i][bitnum(state[i])]=1;}f[1][1][0]=1;for(int r=1;r<n;r++){ memset(f[(r+1)%2],0,sizeof(f[(r+1)%2])); for(int j = 1;j<=statenum;j++){ dfs(r+1,0,state[j],0,0); }} LL ans = 0;for(int i=1;i<=statenum;i++){ ans += f[n%2][i][k];}cout <<ans<<endl;;}int main(){cin >> n>>k;solve(); return 0 ;}
- sgu225 装压DP&位运算
- sgu225:Little Knights(状压DP+打表)
- dp 位运算
- DP+乱搞 位运算
- poj1143 DP+dfs+位运算- -
- 压缩dp的位运算
- zoj 2297【DP+位运算状态压缩】
- HDOJ-2825 AC自动机DP+位运算..
- POJ 3925 - 状态DP.位运算
- DP与位运算的结合
- poj-3071 Football 【概率dp,位运算】
- ZZULIOJ 1921: B 【dp + 位运算】
- LeetCode338. Counting Bits(位运算+DP)
- 点集配对 【dp 位运算】
- poj 3254 状压dp+位运算
- poj 炮兵阵地 状态压缩DP + 位运算
- uva 10817 Headmaster's Headache (DP + 位运算)
- CodeForces 337C Captains Mode(dp+位运算+贪心)
- 字符串专题:H - Blue Jeans(暴力法)
- 基础备忘:类模板总结与补充
- .编写函数进行日期转换
- 字符串专题:I - 统计难题(trie树 改良版)
- 从has no method 'tmpl'谈起
- sgu225 装压DP&位运算
- POJ 1873 The Fortified Forest (计算几何,枚举+凸包)
- iOS-UITextField
- Android仿微信底部菜单
- nginx配置文件上传大小
- mysql配置文件my.cnf详解
- 高仿360手机卫士布局,用来学习布局
- Apache重写URL
- LFI本地包含漏洞利用小技巧