[POJ 3666]Making the Grade[DP]
5111 단어 dp
dp[i][j]=min(dp[i−1][k])+|a[i]−b[j]|(k=0∼j)
이 방정식은 삼방식이어서 이 문제에 대해서는 분명히 T할 것이다.min(dp[i-1][k])이 전 j항의 최소값임을 알아차리면 이동할 때 이 최소값을 유지하면 됩니다.이렇게 하면 제곱의 복잡도를 낮출 수 있다.
개인적인 느낌:
전 n항의 화합, 최소치 등 모두 이렇게 최적화할 수 있다.
구체적인 코드는 다음과 같습니다.
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<string>
#define ll long long
using namespace std;
const int INF = 0x7f7f7f7f;
const int MAXN = 2e3 + 111;
int a[MAXN], b[MAXN];
int dp[MAXN][MAXN];
bool cmp(int a, int b) {
return a > b;
}
int main()
{
int n; cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i], b[i] = a[i];
sort(b, b + n);
for (int i = 0; i < n; ++i) dp[0][i] = abs(a[0] - b[i]);
int ans1 = INF;
for (int i = 1; i < n; ++i) {
int pre = dp[i - 1][0];
for (int j = 0; j < n; ++j) {
pre = min(pre, dp[i - 1][j]);
dp[i][j] = pre + abs(a[i] - b[j]);
}
}
for (int i = 0; i < n; ++i) {
ans1 = min(ans1, dp[n - 1][i]);
}
sort(b, b + n, cmp);
for (int i = 0; i < n; ++i) dp[n - 1][i] = abs(a[n - 1] - b[i]);
int ans2 = INF;
for (int i = n - 2; i >= 0; --i) {
int pre = dp[i + 1][n - 1];
for (int j = n - 1; j >= 0; --j) {
pre = min(pre, dp[i + 1][j]);
dp[i][j] = pre + abs(a[i] - b[j]);
}
}
for (int i = 0; i < n; ++i) {
ans2 = min(ans2, dp[0][i]);
}
cout << min(ans1, ans2) << '
';
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.