結石の問題

問題:遊び場はn個の石の山に囲まれています。隣接する2つの石の山が結合され、最終的に1つの山に統合されるたびに、移動するたびに手間がかかります。強度の代償は、石の2つの山。合計、質問:総労力を最小限に抑える方法。(貪欲ではない)

方法:動的計画法 

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
vector<vector<int>>m;
int digui(int i, int j, vector<int>& arr)
{
	if (m[i][j] != 0)
		return m[i][j];

	if (i == j)
	{
		m[i][j] = arr[i];
		return arr[i];
	}

	if (i == j - 1)
	{
		m[i][j] = arr[i] + arr[j];
		return arr[i] + arr[j];
	}

	int temp = INT_MAX;
	for (int k = i; k < j; k++)
		temp = min(digui(i, k, arr) + digui(k + 1, j, arr), temp);

	m[i][j] = temp;
	return m[i][j];
}
int dp_1(int n,vector<int>&arr)
{
	vector<vector<int>>dp(n + 1, vector<int>(n + 1, 0));
	for (int i = 1; i <=n; i++)
	{
		dp[i][i] = arr[i];
		if(i<n)
			dp[i][i + 1] = arr[i] + arr[i + 1];
	}
	for (int i = n-1; i>=1; i--)
	{
		for (int j = i+1; j <= n; j++)
		{
			int temp = INT_MAX;
			for (int k = i; k < j; k++)
				temp = min(temp, dp[i][k] + dp[k + 1][j]);
			dp[i][j] = temp;

		}
	}
	return dp[1][n];
}
int main()
{
	int n;
	while (cin >> n)
	{
		//m = vector<vector<int>>(n + 1, vector<int>(n + 1, 0));
		vector<int>v;
		v.push_back(0);
		int num = 0;
		for (int i = 1; i <= n; i++)
		{
			cin >> num;
			v.push_back(num);
		}
		//cout << digui(1, n, v);
		cout << dp_1(n, v);
	}


	return 0;
}
/*
7
1 5 7 2 6 9 4
*/

 

おすすめ

転載: blog.csdn.net/weixin_40823740/article/details/109367370