#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Example:
n = 10, I pick 8.
First round: You guess 5, I tell you that it's higher. You pay $5.
Second round: You guess 7, I tell you that it's higher. You pay $7.
Third round: You guess 9, I tell you that it's lower. You pay $9.
Game over. 8 is the number I picked.
You end up paying $5 + $7 + $9 = $21.
分析:明显得,如果把答案设置在为n,采用二分法需要获取的代价是最多的。
假设n=10,最终选取的也是10,
刚开始
low = 1 , high=10 , mid=(1+10)/2=5,付出5 , (low + high)/2
low = 6 , high=10 , mid=8, ( (low+high)/2 + 1 + high ) / 2 = 3/4 * high + 1/4 * low + 1/2
low = 9 , high=10, mid=9 ,
low = 10, high=10 , mid=10,猜中
总共花费=5 + 8 + 9 = 22
n=9,
5+7+8=20
输入:
10
9
输出:
16
14
用动态规划来做:
关键:
1
参考:http://blog.csdn.net/adfsss/article/details/51951658
设任意猜一个数为i,保证获胜说花的钱:
i + max( dp(1,i-1) , dp(i+1,n) )
这里dp(x,y)表示猜范围在(x,y)的数保证能赢应花的钱
遍历1~n作为猜的数,求出其中的最小值就是答案。
2
//递归计算,因为要保证赢,我们一直假设当前猜数i是猜错的,然后一直到最后start >= end,就可以说明猜正确,最后一次耗费0
int temp = i + max( cost(dp , start , i - 1 ) , cost(dp , i+1 , end) );
//对于每个初始猜数i,计算其最多需要多少钱才能猜正确,然后从里面选择一个初始猜数最小的即可
result = min(temp , result);
dp.at(start).at(end) = result;//记录最终结果,便于记忆化搜索
*/
class Solution {
public:
int cost(vector< vector<int> >& dp , int start , int end)
{
if(dp.empty() ||start < 0 || end >= dp.size() || start >= end)
{
return 0;
}
if(dp.at(start).at(end) != 0)
{
return dp.at(start).at(end);
}
int result = INT_MAX;
for(int i = start ; i <= end ; i++)
{
//递归计算,因为要保证赢,我们一直假设当前猜数i是猜错的,然后一直到最后start >= end,就可以说明猜正确,最后一次耗费0
int temp = i + max( cost(dp , start , i - 1 ) , cost(dp , i+1 , end) );
//对于每个初始猜数i,计算其最多需要多少钱才能猜正确,然后从里面选择一个初始猜数最小的即可
result = min(temp , result);
}
dp.at(start).at(end) = result;//记录最终结果,便于记忆化搜索
return result;
}
int getMoneyAmount(int n) {
vector< vector<int> > dp(n + 1 , vector<int>(n+1 , 0));
int result = cost(dp , 1 , n);
return result;
}
};
void process()
{
int num;
Solution solution;
while(cin >> num )
{
int result = solution.getMoneyAmount(num);
cout << result << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
版权声明:本文为qingyuanluofeng原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。