求助
查看原帖
求助
245959
Ender_NaCl楼主2022/1/23 19:53

rt,#4怎么都过不去

//决策单调性优化DP 
#include <iostream>

#include <cstring>

using namespace std;

const int N = 100010;

long long f[21][N],L = 1,R = 0,a[N],j,co[N],ans; //f[j][i]将前i个数划分k段
//f[i][j] = min{f[k][j - 1] + cal(k + 1,i)}

inline void add(int x) 
{ 	
	ans+=co[x];
	co[x]++;
}
inline void del(int x) 
{
	co[x]--;
	ans-=co[x];
}
long long cal(int l, int r) 
{
    while(L > l) add(a[--L]);
    while(L < l) del(a[L++]);
    while(R > r) del(a[R--]);
    while(R < r) add(a[++R]);
    return ans;
}

void solve(int ll,int rr,int l,int r) //从上一层转移下来 
{
	if(l > r) return;
	int Min = 0,mid = (l + r)>>1; 
	long long res = 1e18;
	for(int i = ll;i <= rr;i++) //暴力求解mid最优解 
	{
		long long tmp = cal(i + 1,mid);
		if(f[j - 1][i] + tmp < res) res = f[j - 1][i] + tmp,Min = i;
	}
	f[j][mid] = res;
	solve(ll,Min,l,mid - 1); //分治 
	solve(Min,rr,mid + 1,r);
}

int main()
{
	memset(f,0x3f,sizeof(f)); 
	int n,k,i;
	cin>>n>>k;
	for(i = 1;i <= n;i++) cin>>a[i];
	f[0][0] = 0;
	for(j = 1;j <= k;j++) solve(1,n,1,n); //求解第j层最优解 
	cout<<f[k][n];
	return 0;
}
2022/1/23 19:53
加载中...