ABC163 E - Active Infants
20498 단어 dp
ABC163 E - Active Infants
Question
하나의 그룹을 다시 정렬하고, 각 요소의 수익은 a[i]× l e n m o v e a[i]\times len_{move} a[i]×lenmove, 정렬 후 최대 수익을 구합니다.
Solution
DP는 큰 값을 왼쪽과 오른쪽에 두고, 어느 쪽이 더 늘어나면 어느 쪽에 두는지 생각하기 쉽다. 그러나 양쪽 값과 같은 상황이 존재할 수 있다. 그러면 이때의 선택이 이후의 선택에 영향을 줄 수 있기 때문에 욕심을 부리는 것은 옳지 않다. 여기에 DP를 사용해야 한다.먼저 큰 것부터 작은 것까지 순서를 정한 다음에 매번 선택하지 않은 가장 큰 것을 골라 좌우에 있는 두 가지 상황을 열거한다.d p [ L ] [ R ] = m a x ( d p [ L + 1 ] [ R ] + a n o w × ∣ p o s n o w − L ∣ , d p [ L ] [ R − 1 ] + a n o w × ∣ p o s n o w − R ∣ ) dp[L][R] = max(dp[L+1][R] + a_{now}\times\left | pos_{now} - L\right |,dp[L][R-1]+a_{now}\times\left | pos_{now} - R\right | ) dp[L][R]=max(dp[L+1][R]+anow×∣posnow−L∣,dp[L][R−1]+anow×Posnow - R R∣) 여기서 보면 두 가지 문법이 있는데 하나는 기억화 검색이고 하나는 DP이다. 사실 기억화 검색과 DP는 실제적인 일이라고 느끼고 사상은 이미 찾은 양을 반복하지 않는다.
Code
기억화 검색
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 2e3 + 5;
ll n,dp[N][N];
vector<pair<ll,int> >V(n);
ll DP(int L,int R){
if(R<L) return 0;
if(dp[L][R]!=-1) return dp[L][R];
int i=L+n-1-R;
return dp[L][R]=max(V[i].first*abs(V[i].second-L)+DP(L+1,R),V[i].first*abs(V[i].second-R)+DP(L,R-1));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=0;i<n;i++){int x;cin>>x; V.push_back({x,i});}
sort(V.rbegin(),V.rend());
memset(dp,-1,sizeof(dp));
cout<<DP(0,n-1);
return 0;
}
DP
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 2000 + 5;
int n;
pair<ll,int> a[N];
ll f[N][N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i].first;
a[i].second=i;
}
sort(a,a+n,greater<pair<int,int> >());
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){
int k=i-j;
f[j+1][k]=max(f[j+1][k],f[j][k]+a[i].first*abs(a[i].second-j));
f[j][k+1]=max(f[j][k+1],f[j][k]+a[i].first*abs(n-k-1-a[i].second));
}
}
ll ans=0;
for(int i=0;i<=n;i++) ans=max(ans,f[i][n-i]);
cout<<ans;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.