Garsia–Wachs算法解决石子合并

前排提示:本文并非题解,仅放在题解夹里,若想了解Garsia–Wachs算法原理请跳转:oi_wiki

关于题库有道四边形不等式的题但是无法通过四边形不等式解决

P5569

  • 我们先写\(n^2\)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
constexpr int maxn=2e4+10;
int n;
int s[maxn],f[maxn][maxn],p[maxn][maxn];
void init() {for (int i=1;i<=n;i++) p[i][i]=i;}
int main()
{
	cin >> n;
	for (int i=1;i<=n;i++)
	{
		cin >> s[i];
		s[i]+=s[i-1];
	}
	init();
	for (int l=2;l<=n;l++)
	{
		for (int i=1;i<=n-l+1;i++)
		{
			int j=i+l-1;
			f[i][j]=0x7fffffff;
			for (int k=p[i][j-1];k<=p[i+1][j];k++)
			{
				int x=f[i][k]+f[k+1][j]+s[j]-s[i-1];
				if (f[i][j]>=x)
				{
					f[i][j]=x;
					p[i][j]=k;
				}
			}
		}
	}
	cout << f[1][n] << endl;
	return 0;
}
  • 包炸
  • 介绍新算法的结论我不会告诉你我只知道结论的

有一个数组a[](0 ~ n-1),每次查找最小的k使满足a[k-1]<=a[k+1],将a[k]a[k-1]合并,设和为temp,后k向前找第一个位置设为c满足a[c]>temp,将temp插在c后,每次累加结果,就可以诡异の解决

  • 给出清晰不压行707B运行888KB代码
#include<bits/stdc++.h>
#define endl '\n' 
using namespace std;
constexpr int maxn=1e5+10;
inline int read() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch-'0');ch=getchar();}return x*f;}
int n,ans;
vector<int> l;
int get()
{
	int k=l.size()-2;
	for (int i=0;i<l.size()-2;i++) if (l[i]<=l[i+2]) {k=i;break;}
	int temp=l[k]+l[k+1];
	l.erase(l.begin()+k),l.erase(l.begin()+k);
	int c=-1;
	for (int i=k-1;i>=0;i--) if (l[i]>temp) {c=i;break;}
	l.insert(l.begin()+c+1,temp);
	return temp;
}
int main()
{
	n=read();
	for (int i=1;i<=n;i++) l.push_back(read());
	for (int i=0;i<n-1;i++) ans+=get();
	cout << ans << endl;
	return 0;
}
posted @ 2026-06-02 11:34  msjing  阅读(7)  评论(0)    收藏  举报