【动态规划】Luogu P5774 病毒感染(待补全)

倾然丶 夕夏残阳落幕 提交于 2020-04-04 18:38:22

题目大意

题目链接

n个村庄,每个村庄每天会因传染病去世ai人(除非你治愈这个村庄)。

从1号村庄出发,每天可以选择向相邻的村庄进发或者治愈所在的村庄。

如果在这个过程中之前有未治愈的村庄,同时你往回走了一步,那么你需要把之前未治愈的村庄全部治愈后才能接着自由行动。

求所有村庄都被治愈时最少的死亡人数。

数据范围

n≤3000,ai≤109

样例输入

6
40 200 1 300 2 10

样例输出

1950

样例解释

见链接ヾ(。 ̄□ ̄)ツ゜゜゜

思路

 建议改成:江 苏 题 N B

暴力枚举n3显然不怎么优秀,所以我们选择动态规划。

转移方程:

  dp[j][i+j]=dp[j+1][i+j]+min((sum[i+j]-sum[j])*2,a[j]*i*3+sum[i+j]-sum[j]);

  dp2[i]=min(dp2[i],dp2[j]+dp[j+1][i]+(4*i-4*j-2)*(sum[n]-sum[i]));

代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=3000+10;
 5 ll n,dp[maxn][maxn],dp2[maxn],sum[maxn],a[maxn];
 6 
 7 int main(){
 8     scanf("%lld",&n);
 9     for(ll i=1;i<=n;++i){
10         scanf("%lld",&a[i]);
11         sum[i]=sum[i-1]+a[i];
12     }
13 
14     for(ll i=1;i<=n-1;++i)
15         for(ll j=1;j<=n-i;++j)
16             dp[j][i+j]=dp[j+1][i+j]+min((sum[i+j]-sum[j])*2,a[j]*i*3+sum[i+j]-sum[j]);
17             
18     memset(dp2,0x3f,sizeof dp2);
19     dp2[0]=0;
20     for(ll i=1;i<=n;++i)
21         for(ll j=0;j<i;++j) 
22             dp2[i]=min(dp2[i],dp2[j]+dp[j+1][i]+(4*i-4*j-2)*(sum[n]-sum[i]));
23     
24     printf("%lld",dp2[n]);
25     return 0;
26 }
Luogu P5774

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!