三维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. Java之线程安全中的三种同步方式

    一个程序在运行起来时,会转换为进程,通常含有多个线程. 通常情况下,一个进程中的比较耗时的操作(如长循环.文件上传下载.网络资源获取等),往往会采用多线程来解决. 比如,现实生活中,银行取钱问题.火车 ...

  2. php-自动生成sql语句

    前两天学习到的知识,挺有用的,因此这里做个分享 function AutoCreateSql($tab,$dataarr,$mode='insert',$where=' 1 and 1 limit 1 ...

  3. rabbitMQ教程(三) spring整合rabbitMQ代码实例

    一.开启rabbitMQ服务,导入MQ jar包和gson jar包(MQ默认的是jackson,但是效率不如Gson,所以我们用gson) 二.发送端配置,在spring配置文件中配置 <?x ...

  4. 云计算---openstack镜像制作详解

    一:本地部署KVM 1.安装KVM 1.1安装须知 查看CPU是否支持kvm完全虚拟机. [root@LINUX ~]# grep "flags" /proc/cpuinfofla ...

  5. [编织消息框架][netty源码分析]9 Promise 实现类DefaultPromise职责与实现

    netty Future是基于jdk Future扩展,以监听完成任务触发执行Promise是对Future修改任务数据DefaultPromise是重要的模板类,其它不同类型实现基本是一层简单的包装 ...

  6. 基于阿里云的JavaEE系统框架介绍

    基于阿里云的系统框架展望 1) CDN 用于缓存静态文件等等.七牛和阿里的都还可以. 七牛要做的久一点,各种图片处理的接口要完善一些 阿里的CDN要稍微好一点点,但是没有不安全的访问方式,访问稍微没有 ...

  7. Spring3.x企业开发应用实战读书笔记 —— 第三章IoC容器概述

    声明:    本篇博客绝大多数内容为<Spring3.x企业开发应用实战>一书原内容,所有版权归原书作者所有!,仅供学习参考,勿作他用! 3.2 相关Java基础知识 Java语言允许通过 ...

  8. 快速搭建vsftp 服务器并配置指定目录

    1  搭建vsftp 服务器 前期准备: 1.用root 进入系统 2.使用命令 rpm  -qa|grep vsftpd 查看系统是否安装了ftp,若安装了vsftp,使用这个命令会在屏幕上显示vs ...

  9. python内置函数与匿名函数

    内置函数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() d ...

  10. dotnet core 自定义配置文件

    首先添加一个.json 文件,比如 setting.json 文件内容如下,记得把文件设置为“复制到输出目录” { "ConfigSetting": { "XXXName ...