今天写内网题,连着写了两道区间dp,这里就总结一下。

区间dp思想主要是先枚举f[i][j]中的i,再枚举j,再枚举一个1~j之间的变量k,一般是f[i][j] = max(f[i][j],f[i][k] + f[k][j]);(石子合并)

但是今天遇到的两个都不是这样的。

第一题,复制书稿,洛谷P1282。猜到是区间dp了,但是没写出来。后来看了一下,f[i][j]代表前i个人写到j本书,枚举k为第i个人从第k本书开始写。这样转移方程就很好想了。f[i][j] = min(f[i][j],max(f[i - 1][l],a[l  -  1] + a[l] + a[l + 1] + ... + a[j]),这样复杂度有点高,所以后半部分用前缀和来维护就行了。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int f[][];
int a[],m,n,sum[];
void print(int x, int Ans)
{
if(!x) return;
for(int i=x; i>=; i--)
{
if(sum[x] - sum[i-] > Ans || !i)
{
print(i, Ans);
printf("%d %d\n", i+, x);
break;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = ; i <= n; i++)
{
scanf("%d",&a[i]);
}
memset(f,,sizeof(f));
for(int i = ; i <= n; i++)
sum[i] = sum[i - ] + a[i],f[][i] = sum[i];
for(int i = ; i <= m; i++)
{
for(int j = i; j <= n; j++)
{
for(int l = i; l <= j; l++)
{
f[i][j] = min(f[i][j],max(f[i - ][l - ],sum[j] - sum[l - ]));
}
}
}
print(n,f[m][n]);
return ;
}
/*
9 3
1 2 3 4 5 6 7 8 9
*/

第二题,机器分配,到现在我也不知道为什么是区间dp,但是也只能硬着头皮写了。

第一次,想正常思路,f[i][j]代表i个公司分配j个机器。中间枚举第i个公司分配k个机器。但是貌似过不去,只能的90,因为要按照字典序输出。这个题需要倒着枚举。

#include<cstdio>
#include<iostream>
using namespace std;
int f[][],path[][][];
int num[][],n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i = ;i <= n;i++)
{
for(int j = ;j <= m;j++)
scanf("%d",&num[i][j]);
}
for(int i = ;i <= n;i++)
{
for(int j = ;j <= m;j++)
{
for(int k = ;k <= j;k++)
{
if(f[i - ][j - k] + num[i][k] > f[i][j])
{
f[i][j] = f[i - ][j - k] + num[i][k];
for(int h = ;h < i;h++)
path[i][j][h] = path[i - ][j - k][h];
path[i][j][i] = k;
}
}
}
}
cout<<f[n][m]<<endl;
for(int i = ;i <= n;i++)
{
cout<<i<<" "<<path[n][m][i]<<endl;
}
return ;
}

倒着枚举就是f[i][j]代表i各公司不给j个,然后就好了。

#include<cstdio>
#include<iostream>
using namespace std;
int f[][],path[][][];
int num[][],n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i = ;i <= n;i++)
{
for(int j = ;j <= m;j++)
scanf("%d",&num[i][j]);
}
for(int i = ;i <= n;i++)
{
for(int j = ;j <= m;j++)
{
for(int k = ;k <= j;k++)
{
if(f[i - ][k] + num[i][j - k] > f[i][j])
{
f[i][j] = f[i - ][k] + num[i][j - k];
for(int h = ;h < i;h++)
path[i][j][h] = path[i - ][k][h];
path[i][j][i] = j - k;
}
}
}
}
cout<<f[n][m]<<endl;
for(int i = ;i <= n;i++)
{
cout<<i<<" "<<path[n][m][i]<<endl;
}
return ;
}

动态规划---区间dp的更多相关文章

  1. 动态规划——区间dp

    在利用动态规划解决的一些实际问题当中,一类是基于区间上进行的,总的来说,这种区间dp是属于线性dp的一种.但是我们为了更好的分类,这里仍将其单独拿出进行分析讨论. 让我们结合一个题目开始对区间dp的探 ...

  2. 动态规划——区间DP,计数类DP,数位统计DP

    本博客部分内容参考:<算法竞赛进阶指南> 一.区间DP 划重点: 以前所学过的线性DP一般从初始状态开始,沿着阶段的扩张向某个方向递推,直至计算出目标状态. 区间DP也属于线性DP的一种, ...

  3. 模板 - 动态规划 - 区间dp

    因为昨天在Codeforces上设计的区间dp错了(错过了上紫的机会),觉得很难受.看看学长好像也有学,就不用看别的神犇的了. 区间dp处理环的时候可以把序列延长一倍. 下面是 $O(n^3)$ 的朴 ...

  4. [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

    今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...

  5. Hdu OJ 5115 Dire Wolf (2014ACM/ICPC亚洲区北京站) (动态规划-区间dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目大意:前面有n头狼并列排成一排, 每一头狼都有两个属性--基础攻击力和buff加成, 每一头 ...

  6. Light OJ 1025 - The Specials Menu(动态规划-区间dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1025 题目大意:一串字符, 通过删除其中一些字符, 能够使这串字符变成回文串. ...

  7. [SCOI2007]压缩(动态规划,区间dp,字符串哈希)

    [SCOI2007]压缩 状态:设\(dp[i][j]\)表示前i个字符,最后一个\(M\)放置在\(j\)位置之后的最短字串长度. 转移有三类,用刷表法来实现. 第一种是直接往压缩串后面填字符,这样 ...

  8. [jdoj1090]矩阵_区间dp

    矩阵 jdoj-1910 题目大意:给你连续的n个矩阵的长和宽,保证每连续的两个相邻矩阵满足相乘的条件,不能改变题目中矩阵的位置,求将这些矩阵相乘为一个矩阵的最小乘法次数. 注释:1<=n< ...

  9. 动态规划(区间DP):HDU 5115 Dire Wolf

    Dire wolves, also known as Dark wolves, are extraordinarily large and powerful wolves. Many, if not ...

随机推荐

  1. iOS UIWebView 访问https绕过证书验证的方法

    @implementation NSURLRequest (NSURLRequestWithIgnoreSSL) + (BOOL)allowsAnyHTTPSCertificateForHost:(N ...

  2. Centos7自动式脚本搭建jumpserver

    JumpServer脚本 这里需要安装阿里的yum源和epel源并解压: epel源地址https://mirrors.tuna.tsinghua.edu.cn/epel// 安装阿里互联网yum仓库 ...

  3. chrome本地测试cookie时无效的原因

    https://blog.csdn.net/lyj787505955/article/details/38079079 应该是chrome的原因, 同一网页放在tomcat后,通过localhost方 ...

  4. Linux 系统基础优化和常用命令

    目录 Linux 系统基础优化和常用命令 软连接 tar解压命令 gzip命令 netstart命令 ps命令 kill命令 killall命令 SELinux功能 iptables防火墙 Linux ...

  5. 学习记录--让我打开另一种思路的SQL

    1.显示文章.提交人和最后回复时间 select a.title,a.username,b.adddate from table a, (select max(adddate) adddate fro ...

  6. redis学习三,Redis主从复制和哨兵模式

    Redis主从复制 java架构师项目实战,高并发集群分布式,大数据高可用,视频教程 1.Master可以拥有多个slave 2.多个slave可以连接同一个Master外,还可以连接到其他的slav ...

  7. 暑假集训D18总结

    考试 本来考试时以为能AK的,结果全是因为手贱啊= = T1 瞎XX贪心 我竟然当成了数学 还拍了半天以为是对的 T2 组合数学 太简单 半个小时直接A T3 最长上升(非下降?)子序列 考试25,加 ...

  8. 洛谷 P2155 BZOJ 2186 codevs 2301 [SDOI2008]沙拉公主的困惑

    题目描述 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的 ...

  9. hdu 2242双联通分量+树形dp

    /*先求出双联通缩点,然后进行树形dp*/ #include<stdio.h> #include<string.h> #include<math.h> #defin ...

  10. mysql :=和=的区别

    :=和=的区别 = 只有在set和update时才是和:=一样,赋值的作用,其它都是等于的作用.鉴于此,用变量实现行号时,必须用:= := 不只在set和update时时赋值的作用,在select也是 ...