3638 Moogle
問題概要
数直線上にh個の家があり、それぞれの座標はx[i]である。
このうちc個の家の座標を記録し、残りの家の座標は線形補完により算出することにする。
このとき、それぞれの家の位置の誤差の平均の最小値を出力せよ。
h,c≦200を満たす。
解法
dp[i][j]に、i番目までの家のうち、i番目を記録させ、なおかつ記録した家の数がj個であるときの誤差の最小値をもつと、
dp[i][j]=min{dp[k][j-1]+err[k][i]}の漸化式が立つのでDPできる。
err[k][i]は事前に計算しておき、計算量を節約する。
ソースコード
double dp[201][201],err[201][201]; int main(){ int t,h,c,x[200]; scanf("%d",&t); rep(T,t){ scanf("%d%d",&h,&c); rep(i,h)scanf("%d",x+i); rep(i,h)rep(j,h)dp[i][j]=INF; rep(j,h)rep(i,j) { err[i][j]=0; for(int k=i+1;k<j;k++)err[i][j]+= abs(x[i]+(x[j]-x[i])*1.0*(k-i)/(j-i)-x[k]); } dp[0][1]=0; for(int i=1;i<h;i++)for(int j=2;j<=i+1;j++)rep(k,i) { dp[i][j]=min(dp[i][j],dp[k][j-1]+err[k][i]); } printf("%.4f\n",dp[h-1][c]/h); } return 0; }