当前位置: 代码迷 >> 综合 >> 【POJ3666】Making the Grade
  详细解决方案

【POJ3666】Making the Grade

热度:12   发布时间:2024-01-13 10:09:18.0

题目链接:http://poj.org/problem?id=3666
题意:
这里写图片描述
题解:
首先要发现上述的引理,可以用数学归纳法证明
假设到k这一位置之前所有的b【1~k-1】都是在a【】中出现过的,那么对于b【k】这一个位置,如果a【k】> b【k-1】,那么b【k】=a【k】时是最优的;如果a【k】< b【k-1】,那么一定存在一个值h,使b【h~k】的值都变为a【k】是最优的,或者b【k】=b【k-1】是最优的,而b【k-1】由假设是在a【】中存在的;对于b【1】这个位置,显然b【1】=a【1】是最优的,由数学归纳法可以得知上述引理成立(打这么多字好累啊啊啊)

这时候我们就可以开始DP了
这里写图片描述
好题++

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define F(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int SIZE=2010;
int n,f[SIZE][SIZE];
int a[SIZE],b[SIZE];
int main()
{scanf("%d",&n);F(i,1,n){scanf("%d",&a[i]);b[i]=a[i];}sort(b+1,b+n+1);int m=unique(b+1,b+n+1)-b-1;memset(f,0x3f,sizeof(f));f[0][0]=0;F(i,1,n){int temp=f[i-1][0];F(j,1,m){temp=min(temp,f[i-1][j]);f[i][j]=temp+abs(a[i]-b[j]);}/* F(i,1,n) F(j,1,m) F(k,0,j)f[i][j]=min(f[i][j],f[i-1][k]+abs(a[i]-b[j]));*/int ans=(1<<30);F(i,1,m) ans=min(ans,f[n][i]);cout<<ans<<endl;return 0;
}
  相关解决方案