4月24日一周学习总结

本周博主深入学习了动态规划中的区间DP和线性DP,通过石子合并问题理解了区间DP的通用模板,其中涉及三层循环和状态转移。同时,通过搬寝室问题探讨了线性DP的应用,这道题需要找到最小疲劳值,博主指出此题类似买票问题,需要从几何角度考虑问题。博主强调,掌握这两种DP的关键在于正确识别问题类型和构建动态转移方程。
摘要由CSDN通过智能技术生成

4月24日一周学习总结

区间dp问题

这周继续学习了区间dp问题,还做了线性dp的问题,还认识了背包问题,对于区间dp问题,个人感觉思路较为统一,一般都为三层循环,第一层为区间长度,然后遍历所有区间,再嵌套一层循环,设置标志点,将一个区间分为两段,再在每个区间里取值,然后遍历所有可能。

例题:石子问题(非常经典的区间问题,个人感觉题解可以作为区间dp的一般模板)
共n堆的石子。现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆石子数记为该次合并的得分。求合在一起的最小得分和最大得分。

#include <bits/stdc++.h>
using namespace std;
int w[105],dp[105][105],dp1[105][105],sum[105];
const int inf=0x3f;
int main()
{
    int n;
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));
        memset(dp1,inf,sizeof(dp));
        memset(sum,0,sizeof(sum));
        for(int i=1; i<=n; i++)
        {
            cin>>w[i];
            sum[i]=sum[i-1]+w[i];
            dp1[i][i]=0;
        }
        for(int len=2; len<=n; len++)
        {
            for(int i=1; i<=n; i++)
            {
                int j=i+len-1;
                for(int k=i; k<j; k++)
                {
                    dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
                    dp1[i][j]=min(dp1[i][j],dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1]);
                }
            }
        }
        cout<<dp1[1][n]<<" "<<dp[1][n]<<endl;
    }
    return 0;
}

这道题就是十分经典的区间dp问题,

线性dp问题

搬寝室问题
这道题印象比较深刻的原因主要是寒假听过,也在杭电上交过,这道题动态转移方程一开始并不好想(当时没有做过买票这道题),因为一直在想如何先挑出k件物品,还是老师上课时教会的的。。。
题意:一个人搬宿舍,一次可以同时拿两件物品,两件物体的差值的平方是疲劳度,求n件物品中搬k件的最小疲劳值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[2010][1010],a[2010];
int main()
{
	int n,k,i,j;
	while(cin>>n>>k)
	{
		for(i=1;i<=n;i++)
            cin>>a[i];
		sort(a+1,a+n+1);
		memset(dp,0,sizeof(dp));
		dp[2][1]=(a[2]-a[1])*(a[2]-a[1]);dp[1][1]=999999999;
		for(i=2;i<=n;i++)
		{
			for(j=1;j<=k;j++)
			{
				if(2*j<=i)
				dp[i][j]=min(dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),dp[i-1][j]);
				else dp[i][j]=999999999;
			}
		}
		cout<<dp[n][k]<<endl;
	}
	return 0;
}

当时上课的老师还讲过,如果已经找出k件的话,可以从几何的角度去分析这道题,将条件所给的平方看成面积来做,相邻物体的体积一定小于有间隔的物体,这时候没有调k件的限制,比较好想,现在有了k件就有用dp来进行一次遍历。对于一件物品,无非是拿还是不拿,不拿就的话动态转移方程就继承上一个的疲劳度,如果是拿的话,就要在继承倒数第二个疲劳度的前提下,再加上这次拿的物品与上一个物品构成的的组合,得到这次的疲劳度。(个人感觉类似于买票的那一道题,当前情况都是对于上一次情况和倒数第二层情况的继承和添加)

本周学习感悟与收获

这周是做区间dp的第一周,做的题目还是不算多,一般区间dp的模板都可以套用,但是难点还是在于分析好题目中存在的条件,识别出区间dp的问题,然后再开始根据条件进行循环。区间的本质和线性dp还是非常类似的的,可以从线性dp思维作为切入点,找到dp的方法以及动态转移方程,然后再开始思考如何实现区间dp的区间长度外循环,想要学好区间dp还是要再加深对线性dp的认识和应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值