【プログラミングの問題】ロボットのジャンプの問題

ロボットは古いDOSベースのゲームをプレイしています。ゲームにはN + 1の建物があり、0からNまで番号が付けられ、左から右に配置されています。0の番号が付けられた建物の高さは0単位であり、iの番号が付けられた建物の高さはH(i)単位です。

当初、ロボットは0番の建物にいました。各ステップで、次の(右の)建物にジャンプします。ロボットがk番目の建物にあり、現在のエネルギー値がEであるとすると、次のステップでk +1番目の建物にジャンプします。H(k + 1)とEの差に比例してエネルギーを増減します。H(k + 1)> Eの場合、ロボットはH(k + 1)-Eのエネルギー値を失います。そうでない場合、ロボットはE-H(k + 1)のエネルギー値を取得します。

ゲームの目標はN番目の建物に到達することです。このプロセス中、エネルギー値を負のユニット数にすることはできません。問題は、ゲームの正常な完了を保証するために、ロボットがゲームを開始するエネルギー値はどれくらいかということです。

説明を入力してください:

第一行输入,表示一共有 N 组数据.

第二个是 N 个空格分隔的整数,H1, H2, H3, ..., Hn 代表建筑物的高度

出力の説明:

输出一个单独的数表示完成游戏所需的最少单位的初始能量

例:

输入
5
3 4 3 2 4
输出
4

分析:
エネルギーの損益には2つのタイプがあります:
E(k)= E(k-1)-(H(k)-E(k-1))= 2E(k-1)-H(k)E (k-1)<H(k)
E(k)= E(k-1)+(E(k-1)-H(k))= 2E(k-1)-H(k)E(k -1)<H(k)

次の列の高さに関係なく、E(k)は常に前回のエネルギーE(k-1)の2倍から次の列の長さを引いたものになります-> E(k)= 2E(k-1)- H(k)

したがって、最後のn番目の柱のすべてのエネルギーから逆控除を実行して、探している0番目の柱のエネルギーまで前の柱を徐々に押し出すことができます。

帰納法の手順:

E(n)=2E(n-1)-H(n)
=2*(2E(n-2)-H(n-1))-H(n)
=2^2*(2E(n-3)-H(n-2)-2H(n-1)-H(n)
……
=2^n*E(0)-2^0*H(n-0)-2^1*H(n-1)……-2^(n-1)*H(n-(n-1))
=2^n*E(0)-sum(2^(k)*H(n-k))  k取[0,n-1]

エネルギー量は負ではないため、次のようになります。

E(n)=2^n*E(0)-sum(2^(k)*H(n-k))0  k取[0,n-1]

次にあります:

2^n*E(0)sum(2^(k)*H(n-k))  k取[0,n-1]

次に、両側を同時に2 ^ nで除算すると、次のようになります。

E(0)sum(2^(k)*H(n-k))/2^n
=sum(2^(k)/2^n*H(n-k))
=sum(H(n-k)/2^(n-k)  k取[0,n-1]

つまり、次のように変更します。

E(0)sum(H(i)/2^i)  i取[1,n]

エネルギーが負になることはないため、明らかに浮動小数点数があります。そのため、答えは切り上げる必要があります。

コード:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    
    
	int n,height,ans;
	float sum=0;
	cin >> n;
	for(int i=1;i<=n;i++)
	{
    
    
		cin >> height;
		sum += height/pow(2, i);
	}
	//注:因为要向上取整,所以推荐直接使用ceil()。因为输入数据可能是刚好是2的整幂次数,
	//用int()+1的话有失误的可能-->98%
	ans = ceil(sum);
	cout << ans;
	return 0;
}

付録:
c ++で浮動小数点数を丸めるには、floor()、ceil()、round()、int()の4つのメソッドがあります。これらはすべてcmathヘッダーファイルで定義されており、使用するときにインポートする必要があります。
それらの中で:
floor(x):切り捨て、x以下の整数を取る
ceil(x):
切り上げ、x以上の整数を取るround(x):丸めx
int(x):取るx整数部分

おすすめ

転載: blog.csdn.net/qq_43530773/article/details/114896219