P4158 [SCOI2009]粉刷匠

2023-11-09 15:45
文章标签 scoi2009 p4158 粉刷

本文主要是介绍P4158 [SCOI2009]粉刷匠,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Portal.

DP。

f ( i , j ) f(i,j) f(i,j) 表示前 i i i 条木板粉刷 j j j 次能正确粉刷的最大格子数, g ( i , j , k ) g(i,j,k) g(i,j,k) 表示第 i i i 条木板上粉刷 j j j 次涂了前 k k k 个格子能正确粉刷的最大格子数,用前缀和数组记录蓝色格子数( s u m i , j sum_{i,j} sumi,j表示第 i i i 条木板到位置 j j j 有几个蓝格子),某个区间的格子数减蓝色格子数就是红色格子数。

求能正确粉刷的最大格子数,状态转移方程为: f ( i , j ) = max ⁡ ( f ( i , j ) , f ( i − 1 , j − k ) + g ( i , k , M ) ) f(i,j)=\max(f(i,j),f(i-1,j-k)+g(i,k,M)) f(i,j)=max(f(i,j),f(i1,jk)+g(i,k,M))

g ( i , j , k ) g(i,j,k) g(i,j,k) 的状态转移方程,要考虑前 r r r 个格子正确粉刷的最大格子数加上下一步正确粉刷的格子数(这里要比较一下是正确粉刷的蓝格子多还是红格子多)。
g ( i , j , k ) = max ⁡ ( g ( i , j , k ) , g ( i , j − 1 , r ) + max ⁡ ( s u m i , k − s u m i , r , k − r − s u m i , k + s u m i , r ) g(i,j,k)=\max(g(i,j,k),g(i,j-1,r)+\max(sum_{i,k}-sum_{i,r},k-r-sum_{i,k}+sum_{i,r}) g(i,j,k)=max(g(i,j,k),g(i,j1,r)+max(sumi,ksumi,r,krsumi,k+sumi,r)
代码如下:

#include <bits/stdc++.h>
using namespace std;int f[55][2505],sum[55][2505],g[55][2505][55];
char s[105];int main()
{int N,M,T,ans=0;cin>>N>>M>>T;for(int i=1;i<=N;i++) {cin>>s;sum[i][0]=0;//前缀和初始化for(int j=1;j<=M;j++){if(s[j-1]=='1') sum[i][j]=sum[i][j-1]+1;//记录当前条的蓝色格子数else sum[i][j]=sum[i][j-1];		}}for(int i=1;i<=N;i++)for(int j=1;j<=T;j++)for(int k=1;k<=T;k++)for(int r=j-1;r<k;r++)//因为s数组是从下标为0开始的g[i][j][k]=max(g[i][j][k],g[i][j-1][r]+max(sum[i][k]-sum[i][r],k-r-sum[i][k]+sum[i][r]));for(int i=1;i<=N;i++)for(int j=1;j<=T;j++)for(int k=1;k<=min(j,M);k++)f[i][j]=max(f[i][j],f[i-1][j-k]+g[i][k][M]);for(int i=1;i<=T;i++) ans=max(ans,f[N][i]);cout<<ans;return 0;
}

发现DP题的代码往往很短但是思维含量极高QAQ

这篇关于P4158 [SCOI2009]粉刷匠的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/377061

相关文章

【刷题笔记】删除并获取最大点数粉刷房子

欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 题目一 题目链接:删除并获取最大点数 思路: 预处理状态表示 状态转移方程 代码如下: class Solution {public:int deleteAndEarn(vector<int>& nums) {int N=10001;int arry[N]={0};for(auto x:nums){ar

【BZOJ】1026: [SCOI2009]windy数 数位DP

传送门:【BZOJ】1026: [SCOI2009]windy数 题目分析:数位DP水题。 代码如下: #include <stdio.h>#include <cstring>#include <algorithm>#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )#define For( i ,

BZOJ 1293 [SCOI2009] 生日礼物 题解与分析

1293: [SCOI2009]生日礼物 Time Limit: 10 Sec   Memory Limit:162 MB Submit: 630   Solved: 326   Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩

【动态规划】C++简单多状态dp问题(打家劫舍、粉刷房子、买卖股票的最佳时机...)

文章目录 前言1. 前言 - 理解动态规划算法2. 关于 简单多状态的dp问题2.5 例题按摩师/打家劫舍 3. 算法题3.1_打家劫舍II3.2_删除并获得点数3.3_粉刷房子3.4_买卖股票的最佳时机含冷冻期3.5_买卖股票的最佳时机含手续费3.6_买卖股票的最佳时机III3.7_买卖股票的最佳时机IV 前言 1. 前言 - 理解动态规划算法 关于 动态规划的理解 与例题

1026: [SCOI2009]windy数(数位dp)

1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 12141 Solved: 5770 [Submit][Status][Discuss] Description   windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道, 在A和B之间,包括A和

P4159 [SCOI2009] 迷路(矩阵快速幂,两点路径为k的方案数)

思路: 具体参考https://www.luogu.com.cn/blog/qq-2056188203/mi-lu-scoi2009-ti-xie 简而言之,就是如果权值为1,要求两点之间经过 k k k条边的路径方案数,只要将邻接矩阵进行 k k k次方就好了。 本题权重为1~9,我们将每个点拆成10个点,两个点边权就通过拆成的点建边来表示,这样就成了权值为1的邻接矩阵形式了。 #inc

《剑指 Offer》专项突破版 - 面试题 91 和 92 : 粉刷房屋和翻转字符(C++ 实现)

目录 面试题 91 : 粉刷房子 面试题 92 : 翻转字符   面试题 91 : 粉刷房子 题目: 一排 n 幢房子要粉刷成红色、绿色和蓝色,不同房子被粉刷成不同颜色的成本不同。用一个 n x 3 的数组表示 n 幢房子分别用 3 种颜色粉刷的成本。要求任意相邻的两幢房子的颜色都不一样,请计算粉刷这 n 幢房子的最少成本。例如,粉刷 3 幢房子的成本分别为 [[17, 2

每日OJ题_简单多问题dp④_力扣LCR 091. 粉刷房子

目录 力扣LCR 091. 粉刷房子 解析代码 力扣LCR 091. 粉刷房子 LCR 091. 粉刷房子 难度 中等 假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。 当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是

【bzoj1025】【SCOI2009】【游戏】【dp】

Description windy学会了一种游戏。对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应。最开始windy把数字按顺序1,2,3,……,N写一排在纸上。然后再在这一排下面写上它们对应的数字。然后又在新的一排下面写上它们对应的数字。如此反复,直到序列再次变为1,2,3,……,N。 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6

【SCOI2009】windy数

Description windy定义了一种windy数。 不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 两个整数,A B。 Output 一个整数,表示A~B中有多少个windy数。 Sample Input 1 10 Sample Output 9 Data Constr