ICode9

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

1573 分离与合体(LOJ10151) 区间动规 区间动规合并过程

2022-01-18 16:32:38  阅读:137  来源: 互联网

标签:测试点 int max LOJ10151 maxn 动规 区间 dp


总目录

在线测评地址(ybt)

在线测评地址(LOJ)

1.区间动规 区间动规合并过程

ybt

通过

测试点结果内存时间
测试点1答案正确1708KB8MS
测试点2答案正确628KB2MS
测试点3答案正确656KB2MS
测试点4答案正确764KB2MS
测试点5答案正确788KB2MS
测试点6答案正确1148KB2MS
测试点7答案正确1388KB4MS
测试点8答案正确1640KB7MS
测试点9答案正确1704KB8MS
测试点10答案正确1708KB8MS

LOJ

 题意挺玄乎,弄懂样例是关键。

7
1 2 3 4 5 6 7

dp[1][2]=(1+2)*1=2
dp[2][3]=(2+3)*2=10
dp[3][4]=(3+4)*3=21
dp[4][5]=(4+5)*4=36
dp[5][6]=(5+6)*5=55
dp[6][7]=(6+7)*6=78

dp[1][3]=max(dp[2][3]+(1+3)*1,dp[1][2]+(1+3)*2)=max(14,10)=14
dp[2][4]=max(dp[3][4]+(2+4)*2,dp[2][3]+(2+4)*3)=max(33,28)=33
dp[3][5]=max(dp[4][5]+(3+5)*3,dp[3][4]+(3+5)*4)=max(60,53)=60
dp[4][6]=max(dp[5][6]+(4+6)*4,dp[4][5]+(4+6)*5)=max(95,86)=95
dp[5][7]=max(dp[6][7]+(5+7)*5,dp[5][6]+(5+7)*6)=max(138,127)=138

dp[1][4]=max(dp[2][4]+(1+4)*1,dp[1][2]+dp[3][4]+(1+4)*2,dp[1][3]+(1+4)*3)=max(38,33,29)=38
dp[2][5]=max(dp[3][5]+(2+5)*)
dp[3][6]=
dp[4][7]=

dp[1][5]=
dp[2][6]=
dp[3][7]=

dp[1][6]=
dp[2][7]=

dp[1][7]=

实在写不下去了,编码吧,先看看最大值是否能核上。

核验最值及中间过程的代码如下:

#include <bits/stdc++.h>
#define maxn 310
using namespace std;
unsigned int a[maxn],dp[maxn][maxn];
int main(){
	int n,lt,rt,k,i,len;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%u",&a[i]);
	for(len=1;len<=n-1;len++)
		for(lt=1;lt<=n;lt++){
			rt=lt+len;
			if(rt>n)break;
			for(k=0;k<len;k++)
				dp[lt][rt]=max(dp[lt][rt],dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k]);
			printf("dp[%d][%d]=%u\n",lt,rt,dp[lt][rt]);
		}
	printf("%u\n",dp[1][n]);
	return 0;
}

上述代码对应的输入输出数据如下:

7
1 2 3 4 5 6 7

dp[1][2]=3
dp[2][3]=10
dp[3][4]=21
dp[4][5]=36
dp[5][6]=55
dp[6][7]=78
dp[1][3]=14
dp[2][4]=33
dp[3][5]=60
dp[4][6]=95
dp[5][7]=138
dp[1][4]=38
dp[2][5]=74
dp[3][6]=122
dp[4][7]=182
dp[1][5]=80
dp[2][6]=138
dp[3][7]=212
dp[1][6]=145
dp[2][7]=230
dp[1][7]=238
238

该题需要记录区间合并过程。

打印区域犯难了,再仔细读题,发现,还是对打印区域进行了具体说明:

例如先打印一分为二的区域,然后从左到右打印二分为四的分离区域,然后是四分为八的……

样例对应的分裂过程如下:

b[1][7]
b[1][1] b[2][7] 输出1
b[1][1] b[2][2] b[3][7] 输出2
b[1][1] b[2][2] b[3][3] b[4][7] 输出3
b[1][1] b[2][2] b[3][3] b[4][4] b[5][7] 输出4
b[1][1] b[2][2] b[3][3] b[4][4] b[5][5] b[6][7] 输出5
b[1][1] b[2][2] b[3][3] b[4][4] b[5][5] b[6][6] b[7][7] 输出6

分裂的输出还是比较考验思维的。

基本思路:记录区间动规过程,一遍一遍的打印分裂位置,具体可见代码。

区间动规 区间动规合并过程 代码如下:

#include <bits/stdc++.h>
#define maxn 310
using namespace std;
unsigned int a[maxn],dp[maxn][maxn],b[maxn][maxn],vis[maxn];
int main(){
	int n,lt,rt,k,i,len;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%u",&a[i]);
	for(len=1;len<=n-1;len++)
		for(lt=1;lt<=n;lt++){
			rt=lt+len;
			if(rt>n)break;
			for(k=0;k<len;k++)
				if(dp[lt][rt]<dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k]){
					dp[lt][rt]=dp[lt][lt+k]+dp[lt+k+1][rt]+(a[lt]+a[rt])*a[lt+k];
					b[lt][rt]=lt+k;
				}
		}
	printf("%u\n",dp[1][n]);
	int print=1;//打印分裂过程 
	vis[n]=1;//关键点
	while(print){
		print=0;
		lt=1;
		for(rt=1;rt<=n;rt++)
			if(vis[rt]){
				k=b[lt][rt];
				if(k){
					printf("%u ",k);
					vis[k]=1;
					print=1;
				}
				lt=rt+1;//关键点
			}
	} 
	printf("\n");
	return 0;
}

该题习得了什么?无符号整数的输入与输出。 %u

独立写出了区间动规的分裂过程。

标签:测试点,int,max,LOJ10151,maxn,动规,区间,dp
来源: https://blog.csdn.net/mrcrack/article/details/122331168

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

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

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

ICode9版权所有