[BZOJ1705] [Usaco2007 Nov]Telephone Wire 架设电话线
2016-10-09 12:57
393 查看
要点:DP+辅助数组优化
题解:
由题意易得出DP方程
f[i][j] = min(f[i-1][k]+|j-k|*c+(a[i]-j)*(a[i]-j))
时间复杂度为O(N*100*100)
摘出与k无关项得
f[i][j] = min(f[i-1][k]+|j-k|*c) + (a[i]-j)*(a[i]-j)
记P = min(f[i-1][k]+|j-k|*c) , Q = (a[i]-j)*(a[i]-j)
则f[i][j] = P + Q
易知
P = min(A,B),其中
A = min(f[i-1][k]+(j-k)*c) (k<=j)
B = min(f[i-1][k]+(k-j)*c) (k>j)
A = min(f[i-1][k]-k*c) + j*c
B = min(f[i-1][k]+k*c) - j*c
记C[X][i] = min(f[X][k] - k*c) k∈[1,i]
记D[X][i] = min(f[X][k] + k*c) k∈[i,n]
则A = C[i-1][j] + j*c
则B = D[i-1][j+1] - j*c
显然C、D在任何时刻只需保存X=i-1一行的值
注意高度只能增高,所以h[i]∈[a[i],100]
利用辅助数组优化后,时间复杂度降为O(N*100)
代码:
题解:
由题意易得出DP方程
f[i][j] = min(f[i-1][k]+|j-k|*c+(a[i]-j)*(a[i]-j))
时间复杂度为O(N*100*100)
摘出与k无关项得
f[i][j] = min(f[i-1][k]+|j-k|*c) + (a[i]-j)*(a[i]-j)
记P = min(f[i-1][k]+|j-k|*c) , Q = (a[i]-j)*(a[i]-j)
则f[i][j] = P + Q
易知
P = min(A,B),其中
A = min(f[i-1][k]+(j-k)*c) (k<=j)
B = min(f[i-1][k]+(k-j)*c) (k>j)
A = min(f[i-1][k]-k*c) + j*c
B = min(f[i-1][k]+k*c) - j*c
记C[X][i] = min(f[X][k] - k*c) k∈[1,i]
记D[X][i] = min(f[X][k] + k*c) k∈[i,n]
则A = C[i-1][j] + j*c
则B = D[i-1][j+1] - j*c
显然C、D在任何时刻只需保存X=i-1一行的值
注意高度只能增高,所以h[i]∈[a[i],100]
利用辅助数组优化后,时间复杂度降为O(N*100)
代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath>// #include<algorithm> #include<iostream> using namespace std; #define rep(i,a,b) for(int i=a; i<=b; i++) #define dow(i,a,b) for(int i=a; i>=b; i--) #define tab(i,x) for(int i=head[x]; i!=-1; i=e[i].next) #define cls(a,x) memset(a, x, sizeof a); typedef long long ll; const int INF = 0x3f3f3f3f; const int N = 100010, H = 110; int n,c; int h; int a ; int P,Q,A,B,C[H],D[H]; int f [H]; int main() { scanf("%d%d",&n,&c); rep(i,1,n) scanf("%d",&a[i]); h=a[1]; rep(i,1,n) h=max(h,a[i]); h=min(h,100); cls(f,0x3f); rep(i,1,n) { if(i==1) { rep(j,a[1],h) f[1][j] = (j-a[1])*(j-a[1]); } else { rep(j,a[i],h) { Q = (j-a[i])*(j-a[i]); A = C[j] + j*c; B = D[j+1] - j*c; P = min(A,B); f[i][j] = P + Q; } } C[0] = D[h+1] = INF; rep(j,1,h) C[j] = min(C[j-1], f[i][j] - j*c); dow(j,h,1) D[j] = min(D[j+1], f[i][j] + j*c); } int ans=INF; rep(i,1,h) ans = min(ans, f [i]); printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj1705[Usaco2007 Nov]Telephone Wire 架设电话线(dp优化)
- bzoj 1705;poj 3612:[Usaco2007 Nov]Telephone Wire 架设电话线
- bzoj 1705: [Usaco2007 Nov]Telephone Wire 架设电话线——dp
- bzoj 1705: [Usaco2007 Nov]Telephone Wire 架设电话线【dp】
- 【bzoj1705】[Usaco2007 Nov]Telephone Wire 架设电话线 dp
- [bzoj1705] [Usaco2007 Nov]Telephone Wire 架设电话线
- 【BZOJ】1705: [Usaco2007 Nov]Telephone Wire 架设电话线
- BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP
- 1705: [Usaco2007 Nov]Telephone Wire 架设电话线
- BZOJ1705: [Usaco2007 Nov]Telephone Wire 架设电话线
- 【SPFA+二分答案】BZOJ1614- [Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ1614 [Usaco2007 Jan]Telephone Lines架设电话线 二分/魔性剪枝/最小边长连通
- BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线 二分答案 最短路
- SPFA+二分-BZOJ-1614-[Usaco2007 Jan]Telephone Lines架设电话线
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线【二分+spfa】
- BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- 【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
- 【bzoj1614】【Usaco2007 Jan】Telephone Lines架设电话线 (spfa+二分)题解&代码
- 【BZOJ 1614】: [Usaco2007 Jan]Telephone Lines架设电话线 spfa+二分