首页 > 电脑常识 > 电脑常识

第七周结

admin 电脑常识 2021-04-27 10:13:44 acm竞赛  
后台-系统设置-扩展变量-手机广告位-内容正文底部

这一周以区间dp和打训练赛为主。也尝试了每天写一点博客但是只写了一天的。
区间dp其实还有很多没懂的,但是区间dp有一点区别线性dp简单的地方就是他的模式相对固定,是通过对每个区间进行动态规划,求解区间上的最优解。主要是通过合并小区间的最优解来得出整个打的区间的最优解。我们主要的代码,首先需要枚举区间长度len来当做每个区间的长度,再根据区间长度再次枚举区间的开始点和结束点。最后再根据对每个小区间进行分割来求出小区间的最优解,进而递推出整个区间的最优解。这是区间dp的大体思路但是在实现的时候我总是在死磕他的实现过程,和他的实现的流程,导致我一直不是很理解区间dp,就是有点晕了。也想了好几天最终看了几个朋友的题解有一丝丝的明白了。下面来列出几个例题来巩固巩固。
(1)区间dpA:
有n个聚会求穿衣服的最少量
链接如下:
https://vjudge.net/contest/434302#problem
这个题当初想了还几天,看了别人的题解之后也不明白题解是怎么出来的。后来想了一想我的不理解并不是在于这个题目,而是在于整个区间dp的实现过程。求最少穿衣数,那么我们就需要枚举可以分割的区间来更新答案。分为两个情况,第一种情况就是开始位置和结束位置不相同,不相同的话区间数组+1。相同的话我们首先来看这道题 求给定区间的服装最小值。那么我们把这个区间分为两个区间求这两个区间的最小值然后再合并,把他分为由i到k和由k+1到j两个区间,那么这两个区间再去合并,这两个区间最小值得和就是整个区间的最小值,那么这个dp方程就出来了。**dp方程为dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j])**再处理一下细节每个到每个区间是都+1就行了。当初在这个区间dp的时候就死磕在了他为啥第k件的时候穿上或者脱下要用这一个方程。
(2)能量项链 区间dp P题:
求项链串释放的最大能量。
链接如下:
https://vjudge.net/contest/434302#problem/P
其实这一个题是一个环状的题我们做这种题有一个小细节就是要把这个环展成一个链来解决。合成链之后我们就来根据一的做法来做。把这个整个区间分成两个区间来进行合并求出状态方程来。那么把这分成两个的区间在合并到一起。那么状态方程就是f[l][r]=f[l][k]+f[k][r]+w[l]*w[k]*w[r]。在注意细节就行了

其实这几天主要是绕过区间dp的弯儿来也没做几个题。

再就是这几天的训练这几天的训练开始算法比较多了,还有就是有一些思维的题目,你要是想出来了,那么代码就很简单,你要是想不出来,那么你用平常的方法你就很难把它给做出来。通过这一阵的训练感觉进步还是蛮明显的那些思维题大部分不是很难的还是能够做出来,现在的问题就在于算法和速度和罚时上。算法其实我们也没学多少,就学了贪心、博弈和dp。我们队dp比较差没做出几个来。博弈的话做的那几个题感觉都是博弈里面简单的,那种一般的博弈我们还没见过。速度上因为我们队读题的只有一个人我们另外两个人都看不懂题目导致我们翻译的时候会很慢。还有就是罚时,我有的时候很简单的题目会达不到一次过(这个毛病不仅仅在一次题中了)要不就是这个变量看错了要不就是那个变量看成了其他的。其实我们队最大的需要克服的就是第一点。以后也会加大对算法题的理解和解决。

4月20日

今天学了区间dp花了好几天的时间终于把区间dp里面最简单的那个线性的石子合并看明白了。
关于期间dp有一个套用的公式

memset(dp, 0x3f, sizeof(dp));
for (int i = 1; i <= n; i++) //区间长度为1的初始化
    dp[i][i] = 0;
for (int len = 2; len <= n; len++) //枚举区间长度
{
    for (int i = 1, j = len; j <= n; i++, j++) //区间[i,j]
    {
        //DP方程实现
    }
}

一般的区间dp都会用到二维数组。
我们在做区间dp的题目的时候如果多个数字我们想不到他的最优解法的话可以通过由短区间推到长区间(这好像有一个名词叫做决策性单调)

关于今天的训练,感觉就是针对算法来的,所以我们做的不是很乐观,总结出来无非两点:
(1)我们对算法掌握的还不是很熟悉。
(2)因为体量和英文边长的原因我们的对题目的理解也有一点偏差。
收获:
今天我我在做a的时候发现了sort的一种特别的用法虽然还不知道对不对:

struct ch{
int x,y;
bool flag=false;

}arr[200010];
bool cmp(ch a,ch b)
{
    if((a.y-b.y)==(a.x-b.x))
    {
        a.flag=true;
        b.flag=true;
    }

}
int main()
{
 sort(arr+1,arr+n+1,cmp);
 }

感觉通过这样虽然不能实现排序但是可以起到了选择的目的。

文章来源:https://blog.csdn.net/qq_51769081/article/details/115920138

后台-系统设置-扩展变量-手机广告位-内容正文底部
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
本文地址:https://jcdi.cn/diannaochangshi/diannaochangshi/919.html

留言与评论(共有 0 条评论)
   
验证码:
后台-系统设置-扩展变量-手机广告位-评论底部广告位

教程弟

https://www.jcdi.cn/

统计代码 | 京ICP1234567-2号

Powered By 教程弟 教程弟

使用手机软件扫描微信二维码