1. 程式人生 > >C++ -動態規劃

C++ -動態規劃

1、鋼材切割

程式碼1思路:

將鋼材切割問題優化為:

  1. 鋼材長度n<=10   
  2. 鋼材長度n>10

對於n<=10,可以遍歷迭代解決;對於n>10,可以分段切割,每次切割i=1,2,。。。10十種情況;

此法有個缺點,n較大時迭代時間長,n=30時,計算時長需要37s。

#include <iostream>
#include <string>
#include <time.h>
using namespace std;
int p[11] = { 0,1,5,8,9,10,17,17,20,24,30 };
int max(int a, int b)
{
	if (a >= b) return a;
	else return b;
}
int fun(int *p, int n)
{
	if (n == 0) return 0;
	int q = 0;
	if (n <= 10)
	{
		for (int i = 1; i <= n; i++)
			q = max(q, p[i] + fun(p,n-i));
	}
	else {
		for(int i=1;i<=10;i++)
			q = max(q, p[i] + fun(p, n - i));
	}
	return q;
}
int main()
{
	int n;
	while (cin >> n)
	{
		clock_t start, end;
		start = clock();
		cout << "最佳收益:" << fun(p,n) << endl;
		end = clock();
		cout << "time is " << (double)(end - start) / CLOCKS_PER_SEC << endl;
	}
}

程式碼1優化:

可以維護一張最優值表,減少一些重複的迭代(首先計算n=1-10的最佳值,之後就開始維護一張表p,會發現計算速度越來越快)

#include <iostream>
#include <string>
#include <time.h>
using namespace std;
int a[11]= { 0,1,5,8,9,10,17,17,20,24,30 };//初值表
int p[1000] = {0};//最優表
int max(int a, int b)
{
	if (a >= b) return a;
	else return b;
}
//求解n=1-10的最優質
int  max_val(int *p,int n)
{
	int q = 0;
	for (int i = 1; i <= n; i++)
	{
		q = max(q, p[i] + max_val(p, n - i));
	}
	if (q > a[n])  p[n] = q;
	return q;
}
int fun(int *p, int n)
{
	if (n == 0) return 0;
	if (p[n] != 0) return p[n];//如果已經求解,那麼直接返回值(n<=10已經求解)
	int q = 0;
	for (int i = 1; i < n; i++)
	{
		q = max(q, p[i] + fun(p, n - i));
	}
	if (p[n] < q) p[n] = q;
	return q;
}
int main()
{
	int n;
	//求解n的1-10時候的最小值
	for (int i = 1; i <= 10; i++)
		max_val(a, i);
	for (int i = 1; i <= 10; i++)
		p[i] = a[i];//賦值
	while (cin >> n)
	{
		clock_t start, end;
		start = clock();
		cout << "最佳收益:" << fun(p,n) << endl;
		end = clock();
		cout << "time is " << (double)(end - start) / CLOCKS_PER_SEC << endl;
	}


}

2、軍訓

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
	int N;
	cin >> N;
	while (N--)
	{
		int num;
		cin >> num;
		int left = num;
		vector<bool>  v(num + 1, false);
		while (1)
		{
			if (left > 3)//排除2
			{
				int count = 0;
				for (int i = 1; i <= num; i++)
				{
					if (v[i] == false)
					{
						count++;
					}
					if (count == 2)
					{
						v[i] = true; count = 0; left--;
					}
				}
			}
			if (left <= 3) break;
			if (left > 3)//排除3
			{
				int count = 0;
				for (int i = 1; i <= num; i++)
				{
					if (v[i] == false)
					{
						count++;
					}
					if (count == 3)
					{
						v[i] = true; count = 0; left--;
					}
				}
			}
			if (left <= 3) break;
		}
		for (int i = 1; i <= num; i++)
			if (v[i] == false)
				cout << i << " ";
		cout << endl;
	}
	//getchar();
	//while (1);
	return 0;
}