良い質問dpと定義された状態では、一目見ただけで、この質問は本当に彼は良い状態だと思いませんが、状態は、定義によって、最適なサブ構造を満たすために必要であることができます。より重要な点は、伝達方程式を容易にすることであるがあります。
まず、DPを定義[i]はiが最大数を取得することができます前に、発見がうまく転送されない数を表し、私たちは、私は最大数の数を選択状態j jの前に、1次元表現を追加することを検討してください。これは、状態遷移方程式を描画します。
#include <bits/stdc++.h>
using namespace std;
int n, ans, a[100101], dp[5101][5101];// dp[i][j]表示前i个数里面剩下j个数所得到的最好个数
struct d {
int a, id;
}data[100100];
int main()//不是最长上升子序列。
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &data[i].a);// a[i]=i有多少最多能取多少个
memset(dp, 0, sizeof(dp)); // 使a[i]变成i的值
for (int i = 1; i <= n; i++)
if (data[i].a == i)
dp[i][1] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
{
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]);
if (data[i].a == j)//如果此时的值等于j的话,则该数可以选
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);//如果data[i].a等于j说明,填表法。
}
for (int i = 1; i <= n; i++
)
for (int j = 1; j <= i; j++)
ans = max(dp[i][j], ans);
printf("%d", ans);
return 0;
}
/*
10
1 1 3 3 1 6 4 6 5 10
*/