bzoj1087

解题:国王在棋盘上的摆放方案数

Description

在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

Input

只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

Output

方案数。

Sample Input

3 2

Sample Output

16



状压dp,用三进制表示状态,以下是标准程序


program bzoj1087;
var
  ans:int64;
  o,n,i,j,k:longint;
  tot:array [0..1] of longint;
  thr:array [0..10] of longint;
  dl:array [0..1,0..200001] of record
                                 stu,count:longint;
                               end;
  f:array [0..1,0..31,0..19683] of int64;
  exi:array [0..31,0..19683] of boolean;
 
procedure dfs (no,now,count,stu:longint;p:int64);
var
  x:longint;
begin
  if count>k then exit;
  if no>n then
    begin
      if not exi[count,now] then
        begin
          exi[count,now]:=true;
          f[o,count,now]:=0;
          inc(tot[o]);
          dl[o,tot[o]].count:=count;
          dl[o,tot[o]].stu:=now;
        end;
      f[o,count,now]:=f[o,count,now]+p;
      exit;
    end;
  x:=stu div thr[no-1] mod 3 - 1;
  if x<0 then x:=0;
  dfs(no+1,now+x*thr[no-1],count,stu,p);
  x:=stu div thr[no-1] mod 3;
  if x<2 then
    begin
      x:=now;
      if no>1 then
        x:=x-x div thr[no-2] mod 3 * thr[no-2] + 2 * thr[no-2];
      x:=x-x div thr[no-1] mod 3 * thr[no-1] + 2 * thr[no-1];
      if no<n then
        x:=x-x div thr[no] mod 3 * thr[no] + 2 * thr[no];
      dfs(no+2,x,count+1,stu,p);
    end;
end;
 
 
begin
  read(n,k);
  if n=1 then
    begin
      if k<=1 then writeln(1)
              else writeln(0);
      exit;
    end;
  if k*3>n*n then
    begin
      writeln(0);
      exit;
    end;
  thr[0]:=1;
  for i:=1 to 10 do
    thr[i]:=thr[i-1]*3;
  o:=0;
  tot[o]:=1;
  for i:=0 to n-1 do
    dl[o,1].stu:=dl[o,1].stu+thr[i];
  f[o,0,dl[o,1].stu]:=1;
  for j:=1 to n do
    begin
      o:=o xor 1;
      fillchar(exi,sizeof(exi),false);
      tot[o]:=0;
      for i:=1 to tot[o xor 1] do
        dfs(1,0,
        dl[o xor 1,i].count,
        dl[o xor 1,i].stu,
        f[o xor 1,dl[o xor 1,i].count,dl[o xor 1,i].stu]);
    end;
  for i:=1 to tot[o] do
    if dl[o,i].count=k then
      ans:=ans+f[o,dl[o,i].count,dl[o,i].stu];
  writeln(ans);
end.

然后我生成了下表,排到了rank1

const
quick:array [1..9,1..81] of int64=(
(1,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,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),
(4,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,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),
(9,16,8,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,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),
(16,78,140,79,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,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),
(25,228,964,1987,1974,978,242,27,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(36,520,3920,16834,42368,62266,51504,21792,3600,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(49,1020,11860,85275,397014,1220298,2484382,3324193,2882737,1601292,569818,129657,18389,1520,64,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(64,1806,29708,317471,2326320,12033330,44601420,119138166,229095676,314949564,305560392,204883338,91802548,25952226,4142000,281571,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,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0),
(81,2968,65240,962089,10087628,77784658,450193818,1979541332,6655170642,17143061738,33787564116,50734210126,57647295377,49138545860,31122500764,14518795348,4959383037,1237072414,224463798,29275410,2673322,163088,6150,125,1,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,0,0,0,0,0,0)
);
var
  n,k:longint;
begin
  read(n,k);
  writeln(quick[n,k]);
end.





内容概要:本文围绕六自由度机械臂的人工神经网络(ANN)设计展开,重点研究了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程,并通过Matlab代码实现相关算法。文章结合理论推导与仿真实践,利用人工神经网络对复杂的非线性关系进行建模与逼近,提升机械臂运动控制的精度与效率。同时涵盖了路径规划中的RRT算法与B样条优化方法,形成从运动学到动力学再到轨迹优化的完整技术链条。; 适合人群:具备一定机器人学、自动控制理论基础,熟悉Matlab编程,从事智能控制、机器人控制、运动学六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)建模等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握机械臂正/逆运动学的数学建模与ANN求解方法;②理解拉格朗日-欧拉法在动力学建模中的应用;③实现基于神经网络的动力学补偿与高精度轨迹跟踪控制;④结合RRT与B样条完成平滑路径规划与优化。; 阅读建议:建议读者结合Matlab代码动手实践,先从运动学建模入手,逐步深入动力学分析与神经网络训练,注重理论推导与仿真实验的结合,以充分理解机械臂控制系统的设计流程与优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值