問題の意味
配列を指定して、 あなたは配列に次の操作を行うことができ、任意の回数:
- 対選択隣接のをとが等しい数
- 使用 の代わりに、対数の
複数のアレイ後今、可能な限り最短の長さをシーク。
5
4 3 2 2 3
2
7
3 3 4 4 4 3 3
2
3
1 3 5
3
1
1000
1
問題の解決策
- ステータス: [I、J]アレイが最短長さの範囲を減少させることができる表し
- 追加の配列 示す1の値の範囲の長さを短くすることができる[I、J]場合DP [I] [j]はW [i] [j]は意味を成さないことではない場合には、。2つの配列セクションをマージする決意
- 状態遷移:
- 、このようなkが存在する場合 まあ
#include<cstdio>
#include <iostream>
using namespace std;
#define ll long long
#define pr pair<int, int>
const int maxn=4000;
int n, m, ans;
int a[maxn];
int dp[maxn][maxn], val[maxn][maxn];
int main()
{
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
val[i][i] = a[i]; dp[i][i] = 1;
}
for(int i=n-1;i>0;i--)
{
for(int j=i+1;j<=n;j++)
{
dp[i][j] = 0x3f3f3f3f;
for(int k=i;k<j;k++)
{
if(dp[i][k]+dp[k+1][j] < dp[i][j])
{
dp[i][j] = dp[i][k] + dp[k+1][j];
if(val[i][k]==val[k+1][j] && dp[i][k] == dp[k+1][j] && dp[i][k] == 1)
{
val[i][j] = val[i][k] + 1;
dp[i][j] = 1;
}
}
}
}
}
cout << dp[1][n] << endl;
return 0;
}