dp四边形优化

 

四边形优化资料: https://blog.csdn.net/noiau/article/details/72514812

 

题目链接 :  postoffice已过: https://cn.vjudge.net/problem/POJ-1160

 

 

#include<iostream>

#define maxlen 2001+90
#define maxvalue 1000000000
int c[maxlen];
int cost[maxlen][maxlen];
long long dp[maxlen][maxlen];
int n, m;
int s[maxlen][maxlen];

void getInput()
{
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; ++i)
		scanf("%d", &c[i]);
}

void initcost()
{
	int i;
	for (i = 0; i < n; ++i)
	{
		cost[i][i] = 0;
	}
	for (int i = 2; i <= n; ++i)
	{
		for (int j = 0; j + i - 1 < n; ++j)
		{
			cost[j][j + i - 1] = cost[j][j + i - 2] + c[j + i - 1] - c[(j + j + i - 1) / 2];
		}
	}
}
void process()
{
	initcost();
	int i, j, k;
	//for (k = 2; k <= n; ++k)
	//{
	//	for (i = 0; i<n-k+1; ++i)//i+k-1 < n
	//	{
	//		for (j = i; j < i+k-1; ++j)
	//		{
	//			if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
	//				dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
	//		}
	//		dp[i][i + k - 1] += w[i][i + k - 1];
	//	}
	//}
	int src_max = n - 1;
	int dst_max = m - 1;

	for (i = 0; i <= dst_max; ++i)
	{
		s[i][i] = i;
	}

	for (i = 0; i <= src_max; ++i)
		cost[i + 1][i] = 10000 * 10000;

	i = 0;
	for (j = src_max; j >= 0; --j)
	{
		dp[i][j] = cost[0][j];
		s[i][j] = 0;
	}
	for (i = 1; i <= dst_max; ++i)
	{
		for (j = src_max; j >= 0; --j)
		{
			dp[i][j] = 10000 * 10000;
		}
	}

	int mymin;
	for (i = 1; i <= dst_max; ++i)
	{
		s[i][src_max + 1] = src_max;
		for (j = src_max; j >= i; --j)
		{
			for (k = s[i - 1][j]; k <= s[i][j + 1]; ++k)
			{
				if (dp[i][j] > dp[i - 1][k] + cost[k + 1][j])
				{
					dp[i][j] = dp[i - 1][k] + cost[k + 1][j];
					s[i][j] = k;
				}
			}
		}
	}

}
//void process()
//{
//	int i, j, k;
//	for (i = 0; i < n; ++i)
//	{
//		for (j = 1; j<= n-i; ++j) //i+j-1<n
//		{
//			w[i][j] = w[i][j - 1] + c[j];
//		}
//	}
//
//	//for (k = 2; k <= n; ++k)
//	//{
//	//	for (i = 0; i<n-k+1; ++i)//i+k-1 < n
//	//	{
//	//		for (j = i; j < i+k-1; ++j)
//	//		{
//	//			if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
//	//				dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
//	//		}
//	//		dp[i][i + k - 1] += w[i][i + k - 1];
//	//	}
//	//}
//	for (i = 0; i < n; ++i)
//	{
//		s[i][i] = i;
//	}
//
//	for (k = 2; k <= n; ++k)
//	{
//		for (i = 0; i<n - k + 1; ++i)//i+k-1 < n
//		{
//			for (j = s[i][i + k - 2]; j <= s[i + 1][i + k - 1]; ++j)
//			{
//				if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
//				{
//					s[i][i + k - 1] = j;
//					dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
//				}
//			}
//			dp[i][i + k - 1] += w[i][i + k - 1];
//		}
//	}
//}
void getOutput()
{
	long long result = maxvalue;
	//for(int i=0; i<n; ++i)
	//{
	//	if (result > dp[i][n + i - 1]) result = dp[i][n + i - 1];
	//}
	printf("%lld\n", dp[m-1][n-1]);
	system("pause");
}

int main()
{
	getInput();
	process();
	getOutput();
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值