POJ 3666 Making the Grade 【DP+离散化】
2016-08-09 14:59
399 查看
题目链接
dp[i][j]↔前i个平台高度变成单调递增并且第i个平台高度为j所需的最少花费
所以状态转移:
dp[i][j]=max(dp[i−1][1→j])+|Ai−j|
但是Ai可以高达1E9,显然第二维开不下这么大。但N只有2000,考虑离散化处理。考虑到是要变成非严格单调,如果要改变某个平台的高度,必定是改变成其相邻平台的高度。所以最后每个平台的高度必然是现在已有的所有平台的高度中的某一个。因此记录所有已有的高度,排个序,则dp的第二维就存是第几种高度就可以了。
PS:听说这个题数据很水,只要求出非单调递减就可以了,但是下面的代码还是算了两种情况
题意
有N个平台,它们的高度分别为Ai。先想把这些平台的高度变得非严格单调,改变一个平台的高度的花费就是高度的改变量,问最小的花费是多少。分析
定义状态:dp[i][j]↔前i个平台高度变成单调递增并且第i个平台高度为j所需的最少花费
所以状态转移:
dp[i][j]=max(dp[i−1][1→j])+|Ai−j|
但是Ai可以高达1E9,显然第二维开不下这么大。但N只有2000,考虑离散化处理。考虑到是要变成非严格单调,如果要改变某个平台的高度,必定是改变成其相邻平台的高度。所以最后每个平台的高度必然是现在已有的所有平台的高度中的某一个。因此记录所有已有的高度,排个序,则dp的第二维就存是第几种高度就可以了。
PS:听说这个题数据很水,只要求出非单调递减就可以了,但是下面的代码还是算了两种情况
AC代码
//POJ 3666 Making the Grade //AC 2016-8-8 15:23:59 //DP #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cctype> #include <cstdlib> #include <cstring> #include <vector> #include <set> #include <string> #include <map> #include <queue> #include <deque> #include <list> #include <sstream> #include <stack> using namespace std; #define cls(x) memset(x,0,sizeof x) #define inf(x) memset(x,0x3f,sizeof x) #define neg(x) memset(x,-1,sizeof x) #define ninf(x) memset(x,0xc0,sizeof x) #define st0(x) memset(x,false,sizeof x) #define st1(x) memset(x,true,sizeof x) #define INF 0x3f3f3f3f #define lowbit(x) x&(-x) #define input(x) scanf("%d",&(x)) #define bug cout<<"here"<<endl; //#define debug const int maxn=2005; int N; int A[maxn],B[maxn]; int dp[2][maxn]; int main() { #ifdef debug freopen("E:\\Documents\\code\\input.txt","r",stdin); freopen("E:\\Documents\\code\\output.txt","w",stdout); #endif while(input(N)!=EOF) { for(int i=1;i<=N;++i) input(A[i]); memcpy(B,A,sizeof(A)); sort(B+1,B+N+1); inf(dp); int now=0; for(int i=0;i<=N;++i) dp[now][i]=0; now=!now; for(int i=1;i<=N;++i) { int minn=INF; for(int j=1;j<=N;++j) { minn=min(minn,dp[!now][j]); dp[now][j]=abs(A[i]-B[j])+minn; } now=!now; } int res=INF; for(int i=1;i<=N;++i) res=min(res,dp[!now][i]); inf(dp);now=0; for(int i=0;i<=N;++i) dp[now][i]=0; now=!now; for(int i=N;i>=1;--i) { int minn=INF; for(int j=0;j<=N;++j) { minn=min(minn,dp[!now][j]); dp[now][j]=abs(A[i]-B[j])+minn; } now=!now; } for(int i=1;i<=N;++i) res=min(res,dp[!now][i]); printf("%d\n",res); } return 0; }
相关文章推荐
- Making the Grade poj 3666(离散化+滚动数组+dp)
- 【POJ 3666】Making the Grade(离散化+DP)
- POJ 3666 Making the Grade——DP + 离散化
- poj 3666 Making the Grade dp 离散化
- poj 3666 Making the Grade(dp离散化)
- poj 3666 Making the Grade (有序序列,离散化dp)
- POJ 3666 Making the Grade dp + 离散化
- POJ 3666-Making the Grade (DP+离散化)
- poj 3666 Making the Grade(dp离散化)
- [POJ 3666] Making the Grade (序列DP+离散化)
- POJ3666 Making the Grade [DP,离散化]
- [poj 3666] Making the Grade (离散化 线性dp)
- POJ 3666 Making the Grade【dp】
- poj 3666 Making the Grade 【dp】
- poj3666 Making the Grade dp
- POJ - 3666 Making the Grade(DP)
- POJ 3666 Making the Grade (dp, 数据结构[左偏树, 划分树, 函数式线段树等])
- POJ 3666 Making the Grade (DP)
- POJ 3666 Making the Grade DP
- POJ 3666 Making the Grade (DP+离散化)