Pieces Assignment
Source : zhouguyue | |||
Time limit : 1 sec | Memory limit : 64 M |
Submitted : 267, Accepted : 107
Background
有一个n*m的棋盘(n、m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻)。求合法的方案总数。
Input
本题有多组测试数据,每组输入包含三个正整数n,m和k。
Output
对于每组输入,输出只有一个正整数,即合法的方案数。
Sample Input
2 2 3 4 4 1
Sample Output
0 16
思路:
状态 DP。以行为标准,因为 n * m <= 80,说明因为 8 * 8 = 81 > 80,所以行列不可能同时大于或者等于 8,行列至少有一个是小于8的,故考虑的时候始终让列数小于 8,故一行有无放棋子的可能是 2 ^ 8,因为不要求相邻,所以可以通过一组二进制来表示一行可能存在的棋子的情况。比如该棋盘大小为 4 X 3,那么说明一行可能出现的情况是 000 , 001 , 010 ,100 , 101 5 种情况。而每个二进制数都可以用一个十进制数来表示。用 s 数组记录每个可能情况的二进制所对应的十进制数,用 c 数组记录每个可能情况的二进制所对应的 1 的个数。预处理这些序列之后,就可以递推下去了。
用 dp [ i ] [ j ] [ k ],代表第 i 行时,运用 j 这个二进制的放置方法,所构成到这行为止总共的棋子数为 k 的情况总数。那么:
dp [ i ] [ j ] [ k ] += dp [ i - 1 ] [ a ] [ k - c[ j ] ] (当满足 s [ j ] & s [ a ] == 0 时),最后循环所有 way 的 dp [ n ] [ way ] [ k ] 求得总和即为答案。数组要开 long long,得出的结果也要用 long long 保存,因为情况会爆 int。
AC:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; int n, m, k, way; int c[600], s[600]; ll dp[100][600][25]; void make_num() { for (int i = 0; i < (1 << m); ++i) { int num = i, one = 0; int temp = 0, last = num % 2; num /= 2; if (last) ++one; while (num) { if (num % 2) ++one; if (last && (num % 2)) { temp = 1; break; } last = num % 2; num /= 2; } if (temp) continue; else { ++way; c[way] = one; s[way] = i; } } } void solve() { memset(dp, 0, sizeof(dp)); dp[0][1][0] = 1; for (int i = 1; i <= n; ++i) { for (int kk = 0; kk <= k; ++kk) { for (int p = 1; p <= way; ++p) { if (c[p] > kk) continue; for (int q = 1; q <= way; ++q) { if (!(s[p] & s[q])) { dp[i][p][kk] += dp[i - 1][q][kk - c[p]]; } } } } } ll res = 0; for (int i = 1; i <= way; ++i) { res += dp[n][i][k]; } printf("%lld\n", res); } int main() { while (~scanf("%d%d%d", &n, &m, &k)) { if (n < m) swap(n, m); way = 0; make_num(); solve(); } return 0; }
相关推荐
本资源是北航计算机研究生课程中的算法设计与分析 Assignment_1,涵盖了动态规划和状态空间搜索等算法设计技术。 一、动态规划算法设计 在该Assignment中,我们使用动态规划算法来解决一个生产计划问题。该问题中...
在本篇中,我们将深入探讨MATLAB编程语言及其在完成作业任务中的应用,特别是针对"Assignment 5_matlab_assignment_"这个项目。MATLAB(Matrix Laboratory)是一种强大的数值计算和数据分析软件,广泛应用于科学计算...
在探索编译原理的深奥世界中, ASSIGNMENT 2 作为一次学习的契机,将我们带入了自动机理论和正则表达式的神秘领域。本篇文章将从非确定有限自动机(NFA)开始,逐步深入到确定有限自动机(DFA)、正则语言的补运算...
【标题】"Assignment-2.zip_assignment" 涉及的核心知识点是离散到频率变换(DTFT,Discrete-Time Fourier Transform)。 在数字信号处理领域,离散时间傅立叶变换(DTFT)是一个非常重要的概念。DTFT是将一个离散...
Aurora Lane Assignment分配在设计高性能、高带宽的数据传输系统时起着至关重要的作用。Aurora是一种基于LVDS(低压差分信号)技术的串行链路协议,广泛应用于Xilinx FPGA(现场可编程门阵列)中的GTX或GTH收发器。...
【标题】"Assignment 1_imageprocessing_composedi87_assignment_" 涉及的是一个关于图像处理的项目作业,很可能是计算机科学或相关领域的课程任务。在这个任务中,学生需要运用编程技能,尤其是图像处理技术,来...
### CS193P iOS Application Development - Assignment 1 Walkthrough #### Objective The main objective of this assignment is to reproduce the demonstration given in class, which involves building a ...
【标题】"Assignment4_2.zip" 是一个压缩文件,通常用于存储多个相关文件或文件夹,便于传输和管理。在IT行业中,这样的文件格式广泛应用于项目协作、数据备份和软件分发。这类文件可以使用各种解压工具,如WinRAR、...
Assignment Information Theory
东北大学需求分析Assignment 2 solution 东北大学需求分析Assignment 2 solution 东北大学需求分析Assignment 2 solution 东北大学需求分析Assignment 2 solution 东北大学需求分析Assignment 2 solution东北大学...
在Karel的环境中,调试过程往往直观且易于理解,因为你可以直接观察到Karel的行动和地图的状态变化。这有助于学习者快速理解错误的原因,并学会如何修正。 斯坦福大学的编程方法学课程强调实践和理解编程原理,而...
CS231N计算机视觉公开课的作业答案,只有assignment1,其中包含了作业,还有作业的答案,还有在网上下载的数据集,都在里面了。这个作业是用的anaconda的jupyter来做的。 如果后期的软件下载,或者如何打开使用,...
在Assignment 2中,模型可能包含游戏规则和状态,视图负责显示,控制器处理用户输入和业务逻辑。 10. **编程实践**:这个assignment不仅涵盖了理论知识,还强调了实际编程技巧,如错误处理、内存管理(Swift中的ARC...
5. **状态更新**:根据新的观测和运动模型更新粒子的状态,形成新的状态分布。 通过这个作业,学生不仅可以深入理解Particle Filter的工作原理,还能亲手实践,体验如何将其应用于Robotsoccer的场景中。这不仅锻炼...
【标题】:“Assignment机器学习的代码” 在机器学习领域,编程作业(Assignment)通常涉及到一系列实践性的任务,目的是让学生深入理解和应用所学理论知识。这个压缩包“Assignment机器学习的代码”很可能包含了...
通过这个assignment,我们学习了如何使用动态规划来解决生产规划问题,并且我们也学习了如何定义状态变量、决策变量、状态转移方程和成本函数。同时,我们也学习了如何使用动态规划算法来计算最优成本。 九、延伸...
这篇文档是关于北航2019年算法课程的一个课后作业,主要涉及动态规划(Dynamic Programming, DP)的应用,具体解决的是一个投资优化问题。问题的目标是在有限的投资额下,寻找最优的投资策略以获得最大收益。 首先...
这部分需要学生具备一定的分析能力和抽象思维,能够判断反应趋势,并根据给定条件调整平衡状态。 此外,热化学也是重要的部分,比如反应热的计算、标准摩尔生成焓和标准摩尔燃烧焓的理解,以及盖斯定律的应用。学生...
同时,你可能也接触到了对象的状态管理和更新,以及如何通过定时器来实现游戏的实时性。这些是所有游戏开发的基础,无论是在Java还是其他任何编程语言中。完成这个项目后,你不仅理解了基本的游戏逻辑,还提高了编程...
虽然它们有默认行为,但为了实现更精确的对象状态复制,以及处理复杂数据结构,往往需要自定义这些操作。理解何时和如何自定义这些构造函数和运算符是C++编程中的重要技能,能帮助开发者编写出更加健壮和高效代码。