1.題目大意:
有1-n的村莊,每個村莊在不**的情況下每天死 a[ i ] 人,到達乙個村莊可以**或跳過, 若跳過, 再回頭時只能一直走回這個村莊, 然後才能重新往前走,求最少死亡人數。
2.題目分析
我們定義f[ i ]為前 i 個村莊全部治好的最小代價。令j < i, 在 1-i 內列舉回頭點, 因此我們再定義乙個 g[ i ][ j ] 陣列表示從 i 走到 j 再走回 i 的最小代價, 作為輔助陣列, 在dp的時候輔助求出 f[ i ] 的值。
預處理一下字首和 s 陣列
3.動態轉移方程推導
(1) g陣列:
我們列舉起點 i 和 區間長度 j , 則終點為 i + j
若救 i
w[i+1][i+j] + (s[i+j]-s[i])*2;
救 i 花了一天, 從 i 走到 i+1 花了一天,總共耽誤兩天, 死亡人數 為 i+1 到 j 的總人數 乘以 2, 即(s[i+j]-s[i])*2
若跳過 i
w[i+1][i+j] + 3*j*a[i]+s[i+j]-s[i]
從 i 走到 j 再走回 i 並**從 i+1 到 j 的所有村莊, 耗時 3*j 天。 i 村莊死亡 3*j*a[ i ];
從 i 到 i+1 花了一天, 死亡s[i+j]-s[i]
綜上 w[i][i+j] = w[i+1][i+j]+min((s[i+j]-s[i])*2, 3*j*a[i]+s[i+j]-s[i]);
(2)f陣列
列舉終點 i 和 回頭點 j
f[i] = min(f[i], f[j]+w[j+1][i]+(3*(i-j-1)+i-j+1)*(s[n]-s[i]));
從 j+1 走到 i 回到 j+1, 我們還需再到 i ,耗時 3*(i-(j+1))
從·j 走到 j+1 並** j+1 到 i 的所有村莊 耗時 i-j+1(不理解可以自己畫線段圖看一下)
共死亡(3*(i-j-1)+i-j+1)*(s[n]-s[i]))
4.最後附上**
1 #include2 #include3 #include4 #include5 typedef long long ll;6 using namespace std;
7 const int maxn = 3010;
8 ll a[maxn], s[maxn], f[maxn], w[maxn][maxn];
9 int main()
15 for(int j=1; j19 }
20 memset(f, 0x3f, sizeof(f));
21 f[0] = 0;
22 for(int i=1; i<=n; i++)
26 }
27 printf("%lld\n",f[n]);
28 return 0;
29 }
JSOI 2016 病毒感染 輔助Dp問題
直接看這道題,第乙個困惑點,那個絕對值的比較是什麼東西,根據數學知識,我們可以知道這個意思是k到i的距離小於k到j的距離,而路線是線性的,這就意味著當且僅當k在j的左邊時才成立,不然總會有k i k j,還不理解?看下圖 如果k在k 的位置,那麼k i一定大於k j吧,所以這個題的題意是只要從j往回...
P5774 JSOI2016 病毒感染
題目鏈結 有 n 個小鎮爆發了疫情,其中第 i 個小鎮每天會死 a i 個人,現在從第乙個小鎮出發,每一天可以選擇 求最少死亡人數 n 3000,a i 10 9 可以發現,每個村莊只可能在第一次被經過或第二次被經過時 被 換句話說,在區間 l,r 進行一次往返走 l rightarrow r ri...
B 病毒感染
有一天clccle和rqy走在某個國家的街頭上,機智的rqy卻發現周圍的行人不太對勁,他們嘴裡念念有詞,說著 sqn tql 一邊漫無目的的行走,clccle也發現了這一點,卻驚訝的發覺這種奇怪的病毒會向周圍的城市,最終會感染整個國家,因為網路已經崩潰,所以她們忘記了自己所在的城市,她們唯一知道的是...