三维dp&codeforce 369_2_C

标签: dp


codeforce 369_2_C

题意: 一排树,初始的时候有的有颜色,有的没有颜色,现在给没有颜色的树染色,给出n课树,用m种燃料涂,将相邻相同颜色的树划为一组,最后使得组数为k,并且所用燃料的量最小,给出了每棵树涂j种燃料的用量,如果存在这种涂法输出最小用量,不存在输出-1;

题解: 很容易看出是一个三维dp, dp[i][j][k] 表示处理到第i棵树,最后一棵树为颜色j,现在已经分成的组数为k的时候的最小用量

转移方程如果当前树初始有颜色,那么不能再涂其他颜色,则dp[i][j][k] = min(dp[i-1][j][k],dp[i-1][非j][k-1]);

如果现在树可以涂颜色那么有dp[i][j][k] = min(dp[i-1][j][k] + cost[j],dp[i-1][j][k-1] + cost[j]);

三维dp或者是普通dp要仔细想清楚的都是初始化,还是建议画图,直观的看,在当前的值计算前要先计算出哪些值,这样才可以知道转移的顺序和初始化的值,对于这个题,每次都是从上一次来的,所以对第一层的初始化就很有必要了,可以参考代码看具体如何初始化的,然后要注意是找最小值,所以一开始将所有状态初始化成INF

官方题解:

(它和我定义的有一点点区别,第二维和第三维反了,但是本质不影响)We compute the following array : dp[i][j][k] denoting the minimum amount of paint needed to color the first i trees such that it has beauty j and the i-th tree is colored by color k, and initialize all these values to ∞. We can compute this dp array easily by considering two cases :

1,When the last color used is equal to the current color, then we should compare it with dp[i - 1][j][k] + cost[i][k] if it was originally uncolored or dp[i - 1][j][k] otherwise, since the beauty of the coloring is the same.

2,When the last color used is different from the current color, then we should compare it with dp[i - 1][j - 1][l] + cost[i][k] or dp[i - 1][j - 1][l] for all 1 ≤ l ≤ m except when l is equal to the current color, by similar reasoning.

If the current tree is uncolored, we loop through all the m possible colors to color it.

Naively implementing this dp will give an O(nkm2), which is sufficient to pass for this problem. However, it is possible to optimize it into O(nkm) by avoiding iterating through all colors when considering the last color used and store two global minimums. See the code for more the details.

Time Complexity : O(nkm2) or O(nkm)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<algorithm>
using namespace std;
#define ll long long
const ll INF = (ll)1e18;
const int N = 108;
ll dp[N][N][N];
int init[N];
ll cost[N][N];
int main()
{
int n,m,c;
while(~scanf("%d%d%d",&n,&m,&c))
{
for(int i = 1; i <= n; i++)
{
scanf("%d",&init[i]);
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%I64d",&cost[i][j]);
}
}
for(int i = 0; i <= n; i++)
for(int j = 0; j <= m; j++)
for(int k = 0; k <= c; k++)
dp[i][j][k] = INF;
if(init[1]==0)
{
for(int i = 1; i <= m; i++)
{
dp[1][i][1] = cost[1][i];
}
}
else dp[1][init[1]][1] = 0;
for(int i = 2; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
for(int k = 1; k <= c; k++)
{
if(init[i]!=0)
{
if(j!=init[i]) {
dp[i][j][k] = INF;
continue;
}
else {
for(int u = 1; u <= m; u++)
{
if(u==j) dp[i][j][k] = min(dp[i-1][u][k],dp[i][u][k]);
else if(u!=j) {
dp[i][j][k] = min(dp[i][j][k],dp[i-1][u][k-1]);
}
}
}
}
else if(init[i]==0)
{
for(int u = 1; u <= m; u++)
{
if(u==j){
dp[i][j][k] = min(dp[i-1][j][k] + cost[i][j],dp[i][j][k]);
}
else if(u!=j)
{
dp[i][j][k] = min(dp[i-1][u][k-1] + cost[i][j],dp[i][j][k]);
}
}
}
}
}
}
ll ans = INF;
for(int i = 1; i <= m; i++)
{
ans = min(dp[n][i][c],ans);
}
if(ans==INF)
puts("-1");
else printf("%I64d\n",ans);
}
return 0;
}

三维dp&codeforce 369_2_C的更多相关文章

  1. P1006 传纸条(二维、三维dp)

    P1006 传纸条 输入输出样例 输入 #1 复制 3 3 0 3 9 2 8 5 5 7 0 输出 #1 复制 34 说明/提示 [限制] 对于 30% 的数据,1≤m,n≤10: 对于 100% ...

  2. HDU 5965 三维dp 或 递推

    题意:= =中文题 思路一:比赛时队友想的...然后我赛后想了一下想了个2维dp,但是在转移的时候,貌似出了点小问题...吧?然后就按照队友的思路又写了一遍. 定义dp[i][j][k],表示第i列, ...

  3. 三维dp

    https://cn.vjudge.net/contest/245857#problem/C 代码: #include<iostream> #include<string> # ...

  4. UVA 12063 Zeros and Ones(三维dp)

    题意:给你n.k,问你有多少个n为二进制的数(无前导零)的0与1一样多,且是k的倍数 题解:对于每个k都计算一次dp,dp[i][j][kk][l]表示i位有j个1模k等于kk且第一位为l(0/1) ...

  5. UVALive - 2031 Dance Dance Revolution 三维dp

    题目大意:有一个胖子在玩跳舞机.刚開始的位置在(0,0).跳舞机有四个方向键,上左下右分别相应1,2,3,4.如今有下面规则 1.假设从0位置移动到随意四个位置,消耗能量2 2.假设从非0位置跳到相邻 ...

  6. hdu 4826 三维dp

    dp的问题除了递推过程的设计之外 还有数据结构的选择以及怎样合理的填充数据 这个的填充是个坑..#include<iostream> #include<cstdio> #inc ...

  7. codevs1169传纸条 不相交路径取最大,四维转三维DP

    这个题一个耿直的思路肯定是先模拟.. 但是我们马上发现这是具有后效性的..也就是一个从(1,1)开始走,一个从(n,m)开始走的话 这样在相同的时间点我们就没法判断两个路径是否是相交的 于是在dp写挂 ...

  8. Caesar's Legions(三维dp)

    Caesar's Legions Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u S ...

  9. poj 1037 三维dp

    A decorative fence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7221   Accepted: 272 ...

随机推荐

  1. Python学习日记:day5-------dict字典

    #字典dict------->唯一的映射类型 1.数据类型的划分 数据类型划分为可变数据类型和不可变数据类型. 不可变数据类型:tupe(元组).bool.int.str           可 ...

  2. apache故障处理

    注意:修改虚拟机主机html路径不需要修改主配置这一行. DocumentRoot "/var/www" 1.Permission denied: [client 10.10.2. ...

  3. win10大水牛主机插入耳机没有声音

    主机:大水牛,技嘉主板 操作系统:win10 问题:主机前面插入耳机,没有声音,扬声器图标出错 解决 一..插入耳机 二..Realtek高清晰音频管理器 1.打开音频管理器,点击右下角的设置 2.点 ...

  4. 转 - .net/c# 使用RabbitMQ

    背景 最近需要用C#写一个Adapter来做数据传输,合作方使用的是RabbitMQ,所以我这边也要跟着写写... 在网上搜索了一些,发现园子里的这篇写的还是非常好的.虽然有点老了,我自己用的是最新的 ...

  5. jquery获取select选中的值

    http://blog.csdn.net/renzhenhuai/article/details/19569593 误区: 一直以为jquery获取select中option被选中的文本值,是这样写的 ...

  6. 鸟哥的linux私房菜学习-(四)linux命令的基本概念

    一.命令格式及使用方式 注意到上面的说明当中,『第一个被输入的数据绝对是命令或者是可运行的文件』! 这个是很重要的概念喔!还有,按下[Enter]键表示要开始运行此一命令的意思. 如下效果一样: 二. ...

  7. PCoA主坐标分析

    来源:http://blog.sina.com.cn/s/blog_670445240101nlss.html 1   背景介绍 这是一种排序方法.假设我们对N个样方有了衡量它们之间差异即距离的数据, ...

  8. 用 CSS3 做一个流星雨动画

    昨天 UI 提交过来一个登录页的设计稿,要求背景有一个流星雨动画,做完之后觉得挺有趣,分享一下~ 一.流星动画 首先创建一个 div 作为画布 <div id="stars" ...

  9. 80 行代码爬取豆瓣 Top250 电影信息并导出到 CSV 及数据库

    一.下载页面并处理 二.提取数据 观察该网站 html 结构 可知该页面下所有电影包含在 ol 标签下.每个 li 标签包含单个电影的内容. 使用 XPath 语句获取该 ol 标签 在 ol 标签中 ...

  10. jQuery 文档操作方法 (四)

    方法 描述 addClass() 向匹配的元素添加指定的类名. after() 在匹配的元素之后插入内容. append() 向匹配元素集合中的每个元素结尾插入由参数指定的内容. appendTo() ...