poj2411

本文介绍了一种通过小矩形填充大矩形的不同方式的算法实现。特别关注于使用宽度为2、高度为1的小矩形来填充指定大小的大矩形,并提供了详细的递归搜索方法以计算所有可能的填充方案。

http://www.elijahqi.win/2017/07/07/poj2411/
题目大意:

给出宽为2 高为1的长方形
接下来n行输入数据读入 h w 直到 0 0结束
求出一共有多少种方法可以使单位原始长方形填充满h w的矩形
Description
Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his ‘toilet series’ (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways. Expert as he was in this material, he saw at a glance that he’ll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won’t turn into a nightmare!

Input
The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1<=h,w<=11.

Output
For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.

Sample Input
1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0

Sample Output
1
0
1
2
3
5
144
51205

#include<cstdio>
int state,h,w;
long long f[20][3000];
void dfs1(int i,int p1,int p2,int x){//计算第i行p2状态准备放置x位置 前一行为p1的方案数 
    /*
    if x>w 表示所有列都放完  第i行得到新的状态p2 f[i][p2]+=f[i-1][p1] 第二件事 返回
    if  p1的x位置==0;必须竖放  dfs1(i,p1,p2|1<<x-1,x+1);否则x位置==1{
        x位置可以不放或者横放
        不放:dfs1(i,p1,p2,x+1); 
        准备横放:if (x<w)不出界并且p1的x+1位置不为0 才可以横放  
        dfs(i,p1,p2+(修改xx+1两个位置),x+2);  
    } 
    */
    if (x>w){
        f[i][p2]+=f[i-1][p1];return ;
    }
    if ((p1&(1<<x-1))==0) dfs1(i,p1,p2+(1<<x-1),x+1);else{
        dfs1(i,p1,p2,x+1);
        if (x<w&&((p1&(1<<x))!=0)){
            dfs1(i,p1,p2+(1<<x-1)+(1<<x),x+2);
        }
    }
}
int main(){
    freopen("g1413.in","r",stdin);
    freopen("g1413.out","w",stdout);
    while (1){
        scanf("%d%d",&h,&w);
        if (h==0&&w==0) break;
        state=(1<<w)-1;
        for (int j=0;j<=state;++j) f[0][j]=0;
        f[0][state]=1;

        for (int i=1;i<=h;++i){
            for (int j=0;j<=state;++j) f[i][j]=0;
            for (int j=0;j<=state;++j){
                if (f[i-1][j]!=0){
                    dfs1(i,j,0,1);//四个参数i表示准备放置第i行 i-1行状态是j i行状态从0开始且从第一个位置开始 
                }else continue;
            }

        }
        printf("%I64d\n",f[h][state]);
    }

    return 0;
}
【Koopman】遍历论、动态模态分解和库普曼算子谱特性的计算研究(Matlab代码实现)内容概要:本文围绕【Koopman】遍历论、动态模态分解和库普曼算子谱特性的计算研究展开,重点介绍基于Matlab的代码实现方法。文章系统阐述了遍历理论的基本概念、动态模态分解(DMD)的数学原理及其与库普曼算子谱特性之间的内在联系,展示了如何通过数值计算手段分析非线性动力系统的演化行为。文中提供了完整的Matlab代码示例,涵盖数据驱动的模态分解、谱分析及可视化过程,帮助读者理解并复现相关算法。同时,文档还列举了多个相关的科研方向和技术应用场景,体现出该方法在复杂系统建模与分析中的广泛适用性。; 适合人群:具备一定动力系统、线性代数与数值分析基础,熟悉Matlab编程,从事控制理论、流体力学、信号处理或数据驱动建模等领域研究的研究生、博士生及科研人员。; 使用场景及目标:①深入理解库普曼算子理论及其在非线性系统分析中的应用;②掌握动态模态分解(DMD)算法的实现与优化;③应用于流体动力学、气候建模、生物系统、电力系统等领域的时空模态提取与预测;④支撑高水平论文复现与科研项目开发。; 阅读建议:建议读者结合Matlab代码逐段调试运行,对照理论推导加深理解;推荐参考文中提及的相关研究方向拓展应用场景;鼓励在实际数据上验证算法性能,并尝试改进与扩展算法功能。
本系统采用微信小程序作为前端交互界面,结合Spring Boot与Vue.js框架实现后端服务及管理后台的构建,形成一套完整的电子商务解决方案。该系统架构支持单一商户独立运营,亦兼容多商户入驻的平台模式,具备高度的灵活性与扩展性。 在技术实现上,后端以Java语言为核心,依托Spring Boot框架提供稳定的业务逻辑处理与数据接口服务;管理后台采用Vue.js进行开发,实现了直观高效的操作界面;前端微信小程序则为用户提供了便捷的移动端购物体验。整套系统各模块间紧密协作,功能链路完整闭环,已通过严格测试与优化,符合商业应用的标准要求。 系统设计注重业务场景的全面覆盖,不仅包含商品展示、交易流程、订单处理等核心电商功能,还集成了会员管理、营销工具、数据统计等辅助模块,能够满足不同规模商户的日常运营需求。其多店铺支持机制允许平台方对入驻商户进行统一管理,同时保障各店铺在品牌展示、商品销售及客户服务方面的独立运作空间。 该解决方案强调代码结构的规范性与可维护性,遵循企业级开发标准,确保了系统的长期稳定运行与后续功能迭代的可行性。整体而言,这是一套技术选型成熟、架构清晰、功能完备且可直接投入商用的电商平台系统。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
六、状压DP的优化技巧 6.1 预处理合法状态 很多问题中,大部分状态是不合法的,可以预先筛选: cpp vector valid_states; for (int state = 0; state < (1 << n); ++state) { if (check(state)) { // 检查state是否合法 valid_states.push_back(state); } } 6.2 滚动数组优化 当状态只依赖前一个阶段时,可以节省空间: cpp vector<vector> dp(2, vector(size)); // 只保留当前和上一个状态 int now = 0, prev = 1; for (int i = 1; i <= n; ++i) { swap(now, prev); for (auto& state : valid_states) { dp[now][state] = 0; // 清空当前状态 // 状态转移… } } 6.3 记忆化搜索实现 有时递归形式更直观: cpp int memo[1<<20][20]; // 记忆化数组 int dfs(int state, int u) { if (memo[state][u] != -1) return memo[state][u]; // 递归处理… return memo[state][u] = res; } 七、常见问题与调试技巧 7.1 常见错误 位运算优先级:总是加括号,如(state & (1 << i)) 数组越界:状态数是2ⁿ,不是n 初始状态设置错误:比如TSP中dp[1][0] = 0 边界条件处理不当:如全选状态是(1<<n)-1,不是1<<n 7.2 调试建议 打印中间状态:将二进制状态转换为可视化的形式 cpp void printState(int state, int n) { for (int i = n-1; i >= 0; --i) cout << ((state >> i) & 1); cout << endl; } 从小规模测试用例开始(如n=3,4) 使用assert检查关键假设 八、学习路线建议 初级阶段: 练习基本位操作 解决简单状压问题(如LeetCode 464、526题) 中级阶段: 掌握经典模型(TSP、棋盘覆盖) 学习优化技巧(预处理、滚动数组) 高级阶段: 处理高维状压(如需要同时压缩多个状态) 结合其他算法(如BFS、双指针) 九、实战练习题目推荐 入门题: LeetCode 78. Subsets(理解状态表示) LeetCode 464. Can I Win(简单状压DP) 中等题: LeetCode 526. Beautiful Arrangement LeetCode 691. Stickers to Spell Word 经典题: POJ 2411. Mondriaan’s Dream(棋盘覆盖) HDU 3001. Travelling(三进制状压) 挑战题: Codeforces 8C. Looking for Order Topcoder SRM 556 Div1 1000. LeftRightDigitsGame2 记住,掌握状压DP的关键在于: 彻底理解二进制状态表示 熟练运用位运算 通过大量练习培养直觉 希望这份超详细的教程能帮助你彻底掌握状压DP!如果还有任何不明白的地方,可以针对具体问题继续深入探讨。 请帮我转成markdown语法输出,谢谢
08-13
```markdown # 状压DP优化与实战指南 ## 六、状压DP优化技巧 ### 6.1 预处理合法状态 ```cpp vector<int> valid_states; for (int state = 0; state < (1 << n); ++state) { if (check(state)) { // 自定义合法性检查函数 valid_states.push_back(state); } } ``` ### 6.2 滚动数组优化 ```cpp vector<vector<int>> dp(2, vector<int>(size)); // 双状态数组 int now = 0, prev = 1; for (int i = 1; i <= n; ++i) { swap(now, prev); for (auto& state : valid_states) { dp[now][state] = 0; // 状态初始化 // 转移逻辑... } } ``` ### 6.3 记忆化搜索实现 ```cpp int memo[1<<20][20]; // 根据问题规模调整 memset(memo, -1, sizeof(memo)); int dfs(int state, int u) { if (memo[state][u] != -1) return memo[state][u]; // 递归处理逻辑... return memo[state][u] = res; } ``` ## 七、调试与常见问题 ### 7.1 调试工具函数 ```cpp // 二进制状态可视化 void printState(int state, int n) { for (int i = n-1; i >= 0; --i) cout << ((state >> i) & 1); cout << endl; } // 断言检查示例 assert((1<<n) - 1 == (1 << n) - 1); // 提醒括号重要性 ``` ### 7.2 高频错误清单 1. 位运算优先级误判(总是加括号) 2. 状态空间计算错误(2^n≠n) 3. 初始状态设置错误(特别是边界情况) 4. 全选状态应该是`(1<<n)-1`而非`1<<n` ## 八、学习路线图 | 阶段 | 推荐内容 | 目标 | |------------|-----------------------------------|--------------------------| | **初级** | 位操作基础/LeetCode 78,464 | 理解状态表示 | | **中级** | TSP模型/POJ 2411 | 掌握经典问题建模 | | **高级** | 多状态压缩/CF 8C | 处理复杂状态转移 | ## 九、精选题库 ### 入门必做 - [x] LeetCode 78. 子集(状态表示练习) - [x] LeetCode 464. 我能赢吗(基础状压) ### 经典题库 - [ ] POJ 2411 骨牌覆盖(棋盘类代表) - [ ] HDU 3001 三进制状压(扩展思路) ### 挑战题目 - [ ] Codeforces 8C 物品收集 - [ ] Topcoder SRM556 数字游戏 > **学习建议**:从n≤10的案例开始手工模拟状态转移,逐步建立直觉 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值