leetcode [1444. 切披萨的方案数]
时间:2020-05-12
本文章向大家介绍leetcode [1444. 切披萨的方案数],主要包括leetcode [1444. 切披萨的方案数]使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
(https://leetcode-cn.com/problems/number-of-ways-of-cutting-a-pizza/)
猛一看感觉好吓人,其实最后做出来后在感觉就那样
这题第一眼看上去就像dp,知道这题考的是dp后我们接下来就要写出状态,很明显,切的刀数算一维,接下来我们还要去表示切剩下的披萨,仔细看题就会发现题目设计的很巧妙,它把每次切的披萨的上边或者左边给别人,这表明我们只要定义每块披萨的左上角就能表示这个披萨,即dp[k] [i] [j] 表示在用k刀切成左上角坐标为 i ,j披萨的方案数 ,状态写好然后定义边界即初始状态,原披萨的状态肯定符合题意,初始状态为dp[0] [0] [0] = 1;紧接着要写状态转移式,对于任意的dp [k] [i] [j] 这种状态,它对应着一块左上角坐标为[i] [j] 的披萨,我们想知道它的前一个状态不太容易(即怎么切能到这种状态),但我们很容易就知道它的下一个状态,无非就是横着切或者竖着切,只要符合题意,我们就可以进行状态转移,即:dp[k+1] [x] [y] += dp[k] [i] [j] ,这个转移式为什么是+=,很简单,拿样例1看一下,先切第一行在切第一列和先切第一列再切第一行得到得结果是不一样得,所以有写成+=, 最后在dp[K-1] 维统计一下就行了
const int maxn = 55;
const int MOD = 1e9+7;
int dp[15][maxn][maxn];
class Solution {
public:
int ways(vector<string>& pizza, int K) {
int n = pizza.size(),m = pizza[0].size();
for(int k = 0; k <= K; k++) for(int i = 0; i <= n; i++) for(int j = 0; j <= m; j++) dp[k][i][j] = 0;
dp[0][0][0] = 1; //初始化
for(int k = 0; k < K; k++){
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(dp[k][i][j] == 0) continue;
//H cut 横着切
int sum = 0;
for(int cuti = i; cuti < n-1; cuti++){
if(sum == 0){
for(int cutj = j; cutj < m; cutj++) if(pizza[cuti][cutj] == 'A') sum++;
}
if(sum == 0) continue; // 符合题意才能转移
dp[k+1][cuti+1][j] = (dp[k+1][cuti+1][j]+dp[k][i][j]) % MOD;
}
//V cut 竖着切同理
sum = 0;
for(int cutj = j; cutj < m-1; cutj++){
if(sum == 0){
for(int cuti = i; cuti < n; cuti++) if(pizza[cuti][cutj] == 'A') sum++;
}
if(sum == 0) continue;
dp[k+1][i][cutj+1] = (dp[k+1][i][cutj+1]+dp[k][i][j]) % MOD;
}
}
}
}
int ans = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
int sum = 0;
for(int ni = i; ni < n; ni++){
for(int nj = j; nj < m; nj++){
if(pizza[ni][nj] == 'A') sum++;
}
}
if(sum) ans = (ans+dp[K-1][i][j]) % MOD; // 统计符合题意得答案,因为上面统计得答案是给别人得披萨中一定含有苹果,但你没有保证你剩下得一定有苹果,所以要统计一下
}
}
return ans;
}
};
原文地址:https://www.cnblogs.com/Beic233/p/12877870.html
- 【Scikit-Learn 中文文档】使用 scikit-learn 介绍机器学习 | ApacheCN
- 哈萨比斯:2018年AI最大突破在生物或化学领域
- ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】
- ASP.NET MVC的View是如何被呈现出来的?[设计篇]
- Python大牛告诉你一行代码能干什么?神奇
- 谷歌最新人工智能研究:仅利用稀疏轮廓位置“重构”图像
- DATUM和BigchainDB
- MySQL主从复制的实现过程
- 使用dict和set
- 区块链技术(二):以太坊编程语言Solidity安装及入门初体验
- SQL注入测试神器sqlmap
- 人工智能也分强与弱?
- 【Scikit-Learn 中文文档】集成方法 - 监督学习 - 用户指南 | ApacheCN
- 2017黑科技 颠覆生活哪家强?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux系统集群架构线上项目配置实战(三)
- Linux系统集群架构线上项目配置实战(四)
- Linux系统集群架构线上项目配置实战 五(完结篇)
- 生产Mysql数据库数据恢复实战过程
- voliate工作实际应用场景
- Linux三剑客命令之Awk
- 面试2万月薪必会知识:AQS
- MyBatis XML详解
- Linux三剑客命令之Sed
- Linux运维必会的100道MySql面试题之(四)
- 开源组件ELK日志系统配置与管理
- MySQL集群高可用架构之MHA
- MySQL 主从同步架构中你不知道的“坑”
- Nginx+keepalived高可用配置实战(内附彩蛋)
- MySQL 主从同步架构中你不知道的“坑”(完结篇)