エボリューションゲーム(dpアイデア)
質問:進化する必要のあるモンスターがあります。モンスターの各形態の角の数と目の数を教えてください。角は進化することしかできず、目は範囲です。初期フォームとして任意のフォームを選択し、最大で何回進化できるかを調べることができます。
間違ったアイデアとWAコード
その時のデータを見て、激しくトラバースできるのではないかと思い、最大値を計算したところ、常にWAでした。このような考え方では、フォークする際の条件を満たす最初の値が自動的に選択されるため、最適なソリューションに分類することができます。
*#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
int a, b;
} s[5050];
bool cmp(node c, node d)
{
return c.a < d.a;
}
int main()
{
int n, w, i, j;
cin >> n >> w;
for (i = 1; i <= n; i++)
{
cin >> s[i].a;
s[i].b = i;
}
sort(s + 1, s + n + 1, cmp);
int numm = 0;
for (j = 1; j <= n; j++)
{
int m = s[j].b, num = 0, k = s[j].a;
for (i = j + 1; i <= n; i++)
{
if (s[i].b >= m - w && s[i].b <= m + w && s[i].a > k)
{
m = s[i].b;
k = s[i].a;
num++;
}
}
if (numm < num)
numm = num;
}
cout << numm;
return 0;
}
dpコードとコメント
#include <bits/stdc++.h>
using namespace std;
#define maxn 5050
int h[maxn];
struct node {
int h, e;
}a[maxn];
bool cmp(node x, node y) //sort内置结构体排序函数
{
return x.h < y.h;
}
int dp[maxn];//dp数组存放每个点之前最大的进化次数
int main() {
int n, w;
cin >> n >> w;
for (int i = 1; i <= n; ++i)
{
cin >> a[i].h;
a[i].e = i;
}
sort(a + 1, a + 1 + n, cmp);//按照角的数量进行从小到大的排序
for (int i = 1; i <= n; ++i)
{
for (int j = i + 1; j <= n; ++j)
{
if (a[j].h > a[i].h && abs(a[j].e - a[i].e) <= w) //判断是否符合条件
{
dp[j] = max(dp[j], dp[i] + 1);//更新符合条件的点时最大的进化次数
}
}
}
int maxdp = 0;
for (int i = 1; i <= n; ++i)
maxdp = max(maxdp, dp[i]);//取最大值
cout << maxdp << endl;
return 0;
}