⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 silvercoin.cpp

📁 动态规划解银币问题(C++实现)
💻 CPP
字号:

#include <iostream.h>
const int MAXNUM = 65535;
const int n = 9;
int m[n];
int MinTimes[n + 1], BestDiv[n + 1];

int max(int x, int y){
	if (x > y) return x;
	else return y;
}

int CatchBadCoin(int beginPos, int endPos, int bestDiv){
	static int times = 1;

	int number = endPos - beginPos + 1;
	if (number == 1){
		return beginPos;
	}
	else{
		if (number == 2){
			cout << "  第 " << times++ << " 次:"
				<< "比较 m[" << beginPos << "] "
				<< "和 m[" << endPos << "]." << endl;
			if (m[beginPos] > m[endPos])
				return beginPos;
			else
				return endPos;
		}
		else{
			// Divide all the coins into three parts: k, k and n-2k.
			int sumOfM1 = 0, sumOfM2 = 0;
			for (int i = beginPos; i < beginPos + bestDiv; i++)
				sumOfM1 += m[i];
			for (int j = beginPos + bestDiv; j < beginPos + 2 * bestDiv; j++)
				sumOfM2 += m[j];

			// Does M[0..k-1] == M[k..2k-1] ?
			cout << "  第 " << times++ << " 次:"
				<< "比较 m["
				<< beginPos << ".." << (beginPos + bestDiv - 1)
				<< "] 和 m["
				<< (beginPos + bestDiv) << ".." << (beginPos + 2 * bestDiv - 1)
				<< "]" << endl;
			int newBeginPos, newEndPos, newBestDiv;
			if (sumOfM1 == sumOfM2){
				newBeginPos = beginPos + 2 * bestDiv;
				newEndPos = endPos;
			}
			else{
				if (sumOfM1 > sumOfM2){
					newBeginPos = beginPos;
					newEndPos = beginPos + bestDiv - 1;
				}
				else{
					newBeginPos = beginPos + bestDiv;
					newEndPos = beginPos + 2 * bestDiv - 1;
				}
			}
			newBestDiv = BestDiv[newEndPos - newBeginPos + 1];
			return CatchBadCoin(newBeginPos, newEndPos, newBestDiv);
		}
	}
}

void GetMinTimesAndBestDiv(int n){
	if (n == 0 || n == 1) {
		MinTimes[n] = 0;
		BestDiv[n] = 0;
	}
	else{
		int minTimes = MAXNUM, curTimes = MAXNUM, bestDiv = 0;
		for (int k = 1; k <= n / 2; k++){
			curTimes = max(MinTimes[n-2*k] + 1, MinTimes[k] + 1);
			if (curTimes < minTimes){
				minTimes = curTimes;
				bestDiv = k;
			}
		}
		MinTimes[n] = minTimes;
		BestDiv[n] = bestDiv;
	}
}
		
void main(){
	for (int i = 0; i < n; i++)
		m[n] = 0;
	m[n-1] = 1;
	
	// Step 1: Determine best division for a centain number
	//			(e.g. i) of silver coins.
	/*
	cout << "总共 " << n << " 个银币,其中有一个不合格。"
		<< "其重量如下所示:" << endl;
	for (i = 0; i < n; i++)
		cout << "  第 " << i+1 << " 个,\t重量为 " << m[i] << endl;
	*/
	for (int j = 0; j <= n; j++)
		GetMinTimesAndBestDiv(j);
	cout << endl << "理论上,在最坏情况下:" << endl
		<< "  最少比较(使用天平)次数\t\t" << MinTimes[n] << endl
		<< "  最佳划分点 K(K,K,N-2xK)\t" << BestDiv[n] << endl;
	
	cout << endl << "而实际上," << endl;

	// Step between 1 and 2: Check MinTimes and BestDiv.
	/*
	for (j = 0; j <= n; j++)
		cout << "MinTimes[" << j << "] = " << MinTimes[j] << ", "
			<< "BestDiv[" << j << "] = " << BestDiv[j] << "." << endl;
	*/

	// Step 2: Using weight comparer to find out the bad coin.
	int BadCoinID = CatchBadCoin(0, n - 1, BestDiv[n]);
	cout << endl << "由此可见,不合格的银币为 第 " << (BadCoinID + 1)
		<< " 个,它的重量为 " << m[BadCoinID] << endl;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -