题目大意:

给你一个N和K要求确定有多少种放法,使得没有两个车在一条线上。
N*N的矩阵, 有K个棋子。
题目分析:
我是用DP来写的,关于子结构的考虑是这样的。
假设第n*n的矩阵放k个棋子那么,这个推导过程如下。
 
当我们们第n*n的矩阵的时候可以考虑第(n-1)*(n-1)的矩阵经过哪些变换可以变成n*n的。
如上图蓝色方格。我们加入蓝色方格之后,矩阵就会增大一圈。
1.加入我们蓝色方格不放置棋子。 dp[n-1][k]
2.加入蓝色方格放置一枚棋子,那么我们其实有三种位置可以放置:(1)右侧蓝色(2)底侧蓝色(3)有下角。
对于每一种情况我们放置方格的位置可以有 n-k, 个故: (2*(n-k) + 1) * dp[n-1][k-1]
3.放置两个棋子, 那么放置两个棋子的话肯定不能在左下角放置。故: (n-k)*(n-k)*dp[n-1][k-2]
 
===========================================================================================
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef unsigned long long LL;
const int INF = 1e9+;
const int maxn = ;
const int MOD = ;
LL dp[maxn][];
void solve()
{
for(int i=; i<=; i++)
dp[i][] = ; for(int i=; i<=; i++)
for(int j=; j<=i; j++)
{
dp[i][j] = dp[i-][j] + (*(i-j)+) * dp[i-][j-];
if(j- >= )
dp[i][j] += (i-j+)*(i-j+) * dp[i-][j-];
}
} int main()
{
int T, n, k, cas = ;
solve();
scanf("%d", &T); while(T--)
{
scanf("%d %d", &n, &k);
printf("Case %d: %llu\n",cas++, dp[n][k]);
}
return ;
}
 
 

最新文章

  1. Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)
  2. iOS定时器的使用
  3. Python.with.context-manager
  4. 2016 5.03开始记录我的it学习。
  5. (转)Linux下安装rar fou linux
  6. HTML5应用之时钟
  7. phonegap/cordova 启动页面
  8. js验证 button 提交
  9. 第4章 分治策略 monge阵列
  10. Android APK反编译详解(非常有用)
  11. diff and patch
  12. springboot情操陶冶-web配置(九)
  13. luogu1117 优秀的拆分 (后缀数组)
  14. JAVA学习笔记 (okHttp3的用法)
  15. HBase和MongoDB的区别
  16. [转]SQL server2008 导入超大SQL脚本文件(超过10M)
  17. Scrapy对接selenium+phantomjs
  18. SQL语句嵌套if
  19. springmvc+mybatis 处理图片(二):显示图片
  20. git学习(四):理解git暂存区(stage)

热门文章

  1. oracle中drop、delete和truncate的区别
  2. Echarts使用随笔(1)-Echarts中markPoint的使用(静态、动态)-effect
  3. 转载[POJ题型分类]
  4. Orace数据库锁表的处理与总结&lt;摘抄与总结一&gt;
  5. OC - 19.GCD
  6. 【转】 UITableViewCell的标记、移动、删除、插入
  7. JavaScript HTML DOM 元素(节点)
  8. Perl数组: shift, unshift, push, pop
  9. Java 8 与 .Net的平台发展
  10. PHP-HTML重要知识点笔记