NOI 2.6ダイナミックプランニング1996:登山

2217 ワード

テーマの出所:http://noi.openjudge.cn/ch0206/1996/
1996:山登り
合計時間制限: 5000ms   メモリの制限: 131072kB
説明
メーデーに着いて、PKU-ACMチームはみんなを組織して山に登って観光して、隊員たちは山の上で1つのNつの観光地があることを発見して、しかも順番にこれらの観光地をブラウズすることを決定して、つまり毎回ブラウズした観光地の番号はすべて前のブラウズした観光地の番号より大きいです.また、隊員たちにはもう一つの登山習慣があります.標高の同じ2つの観光地を連続的に閲覧せず、山を下り始めると、上へ行かなくなります.隊員たちは上記の条件を満たすと同時に、できるだけ多くの観光地を閲覧したいと思っていますが、最も多くの観光地を見つけることができますか?
入力
Line 1:N(2<=N<=1000)スポット数Line 2:N個の整数、各スポットの標高
しゅつりょく
最大閲覧できるスポット数
サンプル入力
8
186 186 150 200 160 130 197 220

サンプル出力
4

ソース
第6回北京大学プログラム設計大会及びACM/ICCC選抜試合
-----------------------------------------------------
問題を解く構想.
ダイナミックプランニング
udp[i]:a[i]で終わる最大上昇サブ列長
ddp[i]:a[i]を先頭とする最大下降サブ列長、すなわち、a[i]を先頭とする逆方向の最大上昇サブ列
最大上昇サブカラムの問題を左から右、右から左に2回計算
udp[i]+ddp[i]-1の最大値が問題の解である(-1はa[i]が2回計算されたためである)
-----------------------------------------------------
コード#コード#
#include
#include
using namespace std;

const int NMAX = 1005;
int a[NMAX] = {};
int udp[NMAX] = {};						//     dp, udp[i]:  a[i]            
int ddp[NMAX] = {};						//     dp, ddp[i]:  a[i]            ,      a[i]          

int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin ("0206_1996.txt");
	int n,i,j,mymax;
	fin >> n;
	for (i=0; i> a[i];
	}
	fin.close();
	if (n==2 && a[0]!=a[1])
	{
		cout << n;
		return 0;
	}
	else if (n==2)
	{
		cout << 1;
		return 0;
	}
	else if (n==1)
	{
		cout << 1;
		return 0;
	}

	udp[0] = 1;
	for (i=1; i=0; i--)
	{
		mymax = 0;
		for (j=n-1; j>=i; j--)
		{
			if (a[j]> n;
for (i=0; i> a[i];
}
if (n==2 && a[0]!=a[1])
{
cout << n;
return 0;
}
else if (n==2)
{
cout << 1;
return 0;
}
else if (n==1)
{
cout << 1;
return 0;
}
udp[0] = 1;
for (i=1; i=0; i--)
{
mymax = 0;
for (j=n-1; j>=i; j--)
{
if (a[j]