日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【简●解】[SDOI2008] Sue的小球

發(fā)布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【简●解】[SDOI2008] Sue的小球 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【簡●解】[SDOI2008] Sue的小球

計劃著刷\(DP\)題結(jié)果碰到了這樣一道論文題,幸好不是太難。


【題目大意】

口水話有點多,所以就直接放鏈接。傳送門

【分析】

看到題首先聯(lián)想到了曾經(jīng)做過的關(guān)路燈。所以先按\(x\)值排序,然后進(jìn)行區(qū)間\(DP\)

不妨設(shè)\(f_1[i][j]\)\(f_2[i][j]\)分別表示從起點出發(fā)已射落\(i\)\(j\)這一段彩蛋,當(dāng)前停留在\(i\)點,\(j\)點的最大得分\(v\)

考慮 \(f_1[i][j]\),即點\(i\)是當(dāng)前射擊的彩蛋,射擊的得分與當(dāng)前時刻掛鉤,但 是當(dāng)前的時刻是不能從\(f_1[i][j]\)的狀態(tài)中表示出來的,我們進(jìn)一步考慮 \(f_1[i][j]\)的求解。

由于射擊\(i\)的得分是\(y_i?t?v_i\),而\(t\)等于之前每一步?jīng)Q策移動的時間總和,這樣我們就可以把\(t?v_i\)?在之前的移動中就計算,也就是說每次移動都要把未來會減少的得分計算在內(nèi)。 比如說從\(f_1[i+1][j]\)推到\(f_1[i][j]\),即從\(i+1\)走到\(i\)時除了\(i+1\)\(j\)這一段彩蛋外,其它的彩蛋都在下落,將這丟失的分?jǐn)?shù)一并計算到從\(i+1\)走到\(i\)中。由于\(-t*v_i\)已經(jīng)在之前決策時計算,所以射擊時直接加上\(y_i\)即可。

所以可以先用\(sum[]\)計算\(v_i\)的前綴和,然后\(DP\)方程:
\[ f_1[i][j]=y[i]+max(f_1[i+1][j]+Sum(i+1,j)*(x_{i+1}-x_i),f_2[i+1][j]+Sum(i+1,j)*(x_j-x_i) \]

\[ f_2[i][j]=y[i]+max(f_1[i][j-1]+Sum(i,j-1)*(x_{j}-x_{i}),f_2[i][j-1]+Sum(i,j-1)*(x_j-x_{j-1}) \]

然后\(O(n^2)\)過。

【Code】

#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define ll long long using namespace std; const int MAX = 1000 + 5; const int INF = 0x3f3f3f3f; inline int read(){int f = 1, x = 0;char ch;do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0'||ch>'9');do {x = x*10+ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); return f*x; } int n, bj; double x0, f[3][MAX][MAX], sum[MAX]; struct sakura { double x, y, v; }sak[MAX]; inline bool cmp(sakura a, sakura b) { return a.x < b.x; } inline double Sum(int l, int r) { return sum[n] - sum[r] + sum[l - 1]; } inline double ab(double a) { return a < 0 ? -a : a; } int main(){n = read(); ++n, x0 = read(); sak[1].x = x0, sak[1].y = sak[1].v = 0;for (int i = 2;i <= n; ++i) {sak[i].x = read();}for (int i = 2;i <= n; ++i) {sak[i].y = read();}for (int i = 2;i <= n; ++i) {sak[i].v = read(); }sort(sak + 1, sak + 1 + n, cmp);for (int i = 1;i <= n; ++i) {sum[i] = sum[i - 1] + sak[i].v;if (ab(sak[i].x - x0) <= 1e-10 && ab(sak[i].y) <= 1e-10) {bj = i;}}memset(f, -INF, sizeof (f));f[1][bj][bj] = f[2][bj][bj] = 0.0;for (int k = 1;k <= n; ++k) {for (int i = 1;i + k <= n; ++i) {int j = i + k;f[1][i][j] = sak[i].y + max(f[1][i + 1][j] - (sak[i + 1].x - sak[i].x) * Sum(i + 1, j), f[2][i + 1][j] - (sak[j].x - sak[i].x) * Sum(i + 1, j));f[2][i][j] = sak[j].y + max(f[1][i][j - 1] - (sak[j].x - sak[i].x) * Sum(i, j - 1), f[2][i][j -1] - (sak[j].x - sak[j - 1].x) * Sum(i, j - 1)); }}printf("%.3lf", max(f[1][1][n], f[2][1][n]) / 1000.0);return 0; }

后來聽人說這是未來\(DP\)???

轉(zhuǎn)載于:https://www.cnblogs.com/silentEAG/p/10935723.html

總結(jié)

以上是生活随笔為你收集整理的【简●解】[SDOI2008] Sue的小球的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。