Super Jumping!Jumping!Jumping!(DP最長非減少サブシーケンス)超詳細ソリューション

1.タイトル

最近では「スーパージャンプ!ジャンピング!ジャンピング!" HDUで非常に人気があります。たぶんあなたはいい子で、このゲームについてほとんど知らないので、今から紹介します。
ゲームは2人または2人以上のプレーヤーでプレイできます。これはチェス盤(棋盘)といくつかのチェスマン(棋子)で構成され、すべてのチェスマンは正の整数または「開始」または「終了」でマークされます。プレーヤーは開始点から開始し、最終的に終了点にジャンプする必要があります。ジャンプの過程で、プレイヤーはパスのチェスマンを訪問しますが、全員が1つのチェスマンから別のチェスマンにジャンプする必要があります(開始点が最小で、終了点が最大であると想定できます)。そして、すべてのプレイヤーが後退することはできません。1回のジャンプでチェスマンから次のチェインに移動することも、多数のチェスマンにまたがることもできます。また、開始点から終了点にまっすぐ到達することもできます。もちろん、この状況ではゼロ点が得られます。ジャンプソリューションに従ってより大きなスコアを獲得できる場合にのみ、プレイヤーは勝者となります。
あなたの仕事は、与えられたチェスマンのリストに従って最大値を出力することです。
入力
入力には複数のテストケースが含まれます。各テストケースは、次のように1行で記述されます
。N value_1 value_2…value_N
Nが1000以下であり、すべてのvalue_iが32-intの範囲にあることが保証されます。
0で始まるテストケースは入力を終了し、このテストケースは処理されません。
出力
ケースごとに、ルールに従って最大を出力し、1行を1ケースとして出力します。
入力例

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

出力例

4
10
3

2.質問

不連続に増加するサブシーケンスの累積合計の最大値は、古典的な最長の非減少サブシーケンス問題と同様です。

3.問題解決のアイデア

動的プログラミング
1.状態遷移方程式dp [i] = max(a [i]、dp [j] + a [i])(j <i)。dp [i]は、[i]で終わる最大のサブシーケンス値(非連続)を表します。
2.境界dp [i] = a [i](1 <= i <= n)
3. dp [i…n]をトラバースして最大dp [i]を見つけることが答えです。

4.コード

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e4 + 10;
int dp[maxn],a[maxn]; //dp[i]表示以a[i]结尾的最大递增子序列值(非连续)
int main()
{
	int n;
	while (cin >> n)
	{
		memset(dp, 0, sizeof(dp));  ////每次初始化dp[i]数组
		if (n == 0) break;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			dp[i] = a[i];   //边界
		}
		int ans = -1;   ///记录最大dp[i];
		for (int i = 1; i<= n; i++)
		{
			for (int j = 1; j < i; j++)
			{
				if (a[j] < a[i] && (dp[j] + a[i] > dp[i]))
				{
					dp[i]=dp[j]+a[i]; ////状态转移方程,用于更新dp[i];
				}
			}
			ans = max(ans, dp[i]);
		}
		cout << ans << endl;
	}
	return 0;
}
元の記事を7件公開しました 賞賛されました0 訪問数66

おすすめ

転載: blog.csdn.net/weixin_45629285/article/details/105599495