ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-04-24

2021-04-24 20:32:15  阅读:134  来源: 互联网

标签:24 f1 f2 dp1 04 int sum 2021 dp


acm每周总结

这个星期我们学习了区间dp,通过本周学习我总结一下,这种题型的解题思路。
1.区间长度定义
2.定左端点(通过左端点定右端点)
3.在子区间里寻找分界点并考虑区间dp动态方程,说实话(我认为只要把例子中从区间长度为三推到四,基本上就可以大致推出dp动态规划方程)
4.base case(这个也很重要,好的初始设置是成功解题的关键,可以省很多事)

原始代码

base case
dp[][]=
for(int len=;len<=n;len++)
{for(int r=1,l=len;l<n;l++,r++)
{for(int k=r;k<l;k++)
{dp方程;}}}

例题vjq

一条直线上有n个石子,两两合并问,所合并的最大和最小值。
Sample Input
3
1 2 3
Sample Output
9 11
解题思路
1.根据区间dp思路思考
dp方程
dp1[l][r]=max(dp1[l][r],dp1[l][k]+dp1[k+1][r]+sum[r]-sum[l-1]);
dp2[l][r]=min(dp2[l][r],dp2[l][k]+dp2[k+1][r]+sum[r]-sum[l-1])
即每次和
dp[l][r]=max/min(dp[l][r],dp[l][k]+dp1[k+1][r]+合并花费值);
合并花费值只需将左端点的总花费减右端点即可
2.base case的确定
memset(dp2,0x3f3f3f3f3f,sizeof(dp2));
memset(dp1,0,sizeof(dp1));
memset(sum,0,sizeof(sum));
r=l时dp[r][l]=0
代码实现
#include
#include
#include
using namespace std;
long long a[105],sum[105],f1[105][105],f2[105][105];
int n;
int main()
{
while(cin>>n)
{memset(f2,0x3f3f3f3f3f,sizeof(f2));
memset(f1,0,sizeof(f1));
memset(sum,0,sizeof(sum));
for(int q=1;q<=n;q++)
{cin>>a[q];
sum[q]=sum[q-1]+a[q];
f2[q][q]=0;
f1[q][q]=0;
}
for(int q=1;q<n;q++)
{for(int w=1;w<=n-q;w++)
{int r=w+q;
for(int e=w;e<r;e++)
{f1[w][r]=max(f1[w][r],f1[w][e]+f1[e+1][r]+sum[r]-sum[w-1]);
f2[w][r]=min(f2[w][r],f2[w][e]+f2[e+1][r]+sum[r]-sum[w-1]);}}
}
long long maxx=f1[1][n];
long long minn=f2[1][n];
cout<<minn<<" "<<maxx<<endl;
}
return 0;
}

环形问题思路

这是本周遇到的一个典型的问题只需在
数组输出时在后将数在遍历一遍即可,并考虑在直线基础上区间取值的改动

标签:24,f1,f2,dp1,04,int,sum,2021,dp
来源: https://blog.csdn.net/m0_55758733/article/details/116102422

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有