1 条题解
-
0
自动搬运
来自洛谷,原作者为

shadowice1984
これが勘違いでも、これが勘違いでも搬运于
2025-08-24 21:55:08,当前版本为作者最后更新于2018-04-22 15:39:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
阅读理解题……
所有的东西都是从0开始标号的……因此,也就是说,棋子在中间那行……所以可以打前面一行也可以打后边一行,因此我们只需要状态压缩一行就可以了……
因此合法的方案最多只有64种……考虑到不合法的情况,会更少……
因此可以使用矩阵快速幂优化……(话说为什么n只有啊明明可以开到的)现在来讲如何列dp式子好了
(如果不会矩阵快速幂优化的话可以先去写写其他的题,这里就不讲了)
我们一次填一行棋子表示决策到了第i行,j是一个仅在二进制下有意义的数字,j的第p位为0或1表示第i行第p列是否有棋子,当然显然有些j的情况本来就是不合法的,所以先打个表把所有合法的j值打出来
然后我们再把每种状态找出来那么如何状态i能否转移j呢,直接打一个每一种集合可以攻击到的集合的表,然后判断下两个集合是否可以相互攻击到,如果不可以相互攻击到的话,就不可以转移到了
代码方面,为了好写的话,可以把输入的表格转化成二进制集合,然后处理出每种行集合的情况可以攻击的集合,然后就可以快速判断了,注意为了方便,我们假定每个棋子都攻击不到自己……
上代码~
#include<cstdio> #include<algorithm> using namespace std;const int N=80;typedef unsigned int uit; int n;int m;int p;int k;uit t[N][N];int up;int bk[N][N];uit ans; int at[3];int att[3][N];int zt[N];int ct;bool book[N];int lg[N]; struct mar//矩阵类 { uit mp[N][N]; void operator *=(const mar& b) { for(int i=1;i<=ct;i++)for(int j=1;j<=ct;j++)t[i][j]=0; for(int i=1;i<=ct;i++) for(int k=0;k<=ct;k++) for(int j=1;j<=ct;j++) t[i][j]+=mp[i][k]*b.mp[k][j]; for(int i=1;i<=ct;i++)for(int j=1;j<=ct;j++)mp[i][j]=t[i][j]; } }tr,res,st; int main() { scanf("%d%d%d%d",&n,&m,&p,&k); for(int i=0;i<3;i++) {for(int j=0,t;j<p;j++){scanf("%u",&t);at[i]+=(1<<j)*t;}}at[1]-=(1<<k); up=(1<<m);zt[++ct]=0;book[0]=true;//先把表格转化成二进制集合,钦定自己不可以攻击自己的 for(int i=1;i<up;i++)//然后处理每个集合可以攻击的集合 { for(int j=0,p=i;p;p>>=1,j++) { if((p&1)==0){continue;} att[0][i]|=(j<k)?at[0]>>(k-j):at[0]<<(j-k); att[1][i]|=(j<k)?at[1]>>(k-j):at[1]<<(j-k); att[2][i]|=(j<k)?at[2]>>(k-j):at[2]<<(j-k); } } for(int i=1;i<up;i++){if((i&att[1][i])==0){zt[++ct]=i;}}//判定一下合法的状态 for(int p1=1;p1<=ct;p1++)//然后判断两个状态是否可以转移 { for(int p2=1;p2<=ct;p2++) {if((att[2][zt[p1]]&zt[p2])==0&&(att[0][zt[p2]]&zt[p1])==0){tr.mp[p1][p2]++;}} } for(int i=1;i<=ct;i++){res.mp[i][i]=1;}st.mp[1][1]=1;//矩阵快速幂 for(;n;n>>=1,tr*=tr){if(n&1){res*=tr;}}st*=res; for(int i=1;i<=ct;i++){ans+=st.mp[1][i];}printf("%u",ans);return 0;//拜拜程序~ }
- 1
信息
- ID
- 2929
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者