专栏文章

题解:SP16809 EST - Estimation

SP16809题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipe4q6t
此快照首次捕获于
2025/12/03 10:31
3 个月前
此快照最后确认于
2025/12/03 10:31
3 个月前
查看原文
给出一种 O(n2k)O(n^2k) 的简单做法。
考虑一个简单的 dp,状态设计是 dpi,j,kdp_{i,j,k} 表示考虑到第 ii 个数,现在是第 jj 段,现在的值是 aka_k 的时候的答案。
dpi,j,k=min{mint=1n{dpi1,j1,t},dpi1,j,k}+aiakdp_{i,j,k}=\min\{\min_{t=1}^{n}\{dp_{i-1,j-1,t}\},dp_{i-1,j,k}\}+|a_i-a_k|
解释一下,就是分别讨论从 ii 新开一段或继承前面一段的答案。
我们发现 mint=1n{dpi1,j1,t}\min_{t=1}^{n}\{dp_{i-1,j-1,t}\} 可以预处理出来,就是 O(n2k)O(n^2k) 的了。
CPP
// Problem: Estimation
// Contest: SPOJ - Classical
// URL: https://www.spoj.com/problems/EST/
// Memory Limit: 1536 MB
// Time Limit: 6000 ms
// Author: Binah_cyc

#include<bits/stdc++.h>
using namespace std;
// #define int long long
bool startmb;
constexpr int N=2e3+5;
int n,k,a[N];

int dp[N][30][N],cyc[N][30];

int read()
{
	int x=0,f=1;
	char c=getchar();
	while(!isdigit(c)) f=c=='-'?-1:f,c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*f;
}

bool endmb;
main()
{
	cerr<<((&endmb-&startmb)/1024.0/1024);
	cin.tie(0)->sync_with_stdio(false);
	while((n=read())&&(k=read()))
	{
		for(int i=1;i<=n;i++) a[i]=read();
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<=k&&j<=i;j++)
			{
				for(int k=1;k<=n;k++) dp[i][j][k]=0x3f3f3f3f;
				cyc[i][j]=0x3f3f3f3f;
			}
		}
		for(int i=1;i<=n;i++) dp[0][0][i]=0;
		cyc[0][0]=0;
		for(int i=1;i<=n;i++) for(int j=1;j<=k&&j<=i;j++) for(int k=1;k<=n;k++) dp[i][j][k]=min(dp[i-1][j][k],cyc[i-1][j-1])+abs(a[i]-a[k]),cyc[i][j]=min(cyc[i][j],dp[i][j][k]);
		int ans=INT_MAX;
		for(int i=1;i<=k;i++) ans=min(ans,cyc[n][i]);
		cout<<ans<<'\n';
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...