4038: 医疗援助4856: [Jsoi2016]病毒感染

xiaoxiao2021-02-28  24

题目链接

nn1,2,niai1/iai,ii+1,

g[i][j]jijij,g[i][i]=0,j,3(ij)ja[j]1sum[j+1,i]

g[i][j]=g[i][j+1]+sum[j+1,i]+min((ij)3a[j],sum[j+1,i])

f[i]i

jj+1ij+1i3(i(j+1))(ij+1)4(ij)2sum[i+1,n]

f[i]=min(f[j]+g[i][j+1]+sum[i+1,n]((ij)42))

我的收获:真–脑洞……辅助dp……挺常用的……

#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define ll long long const int M=3005; int n,a[M]; ll s[M],g[M][M],f[M]; int read() { int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline ll sum(int l,int r){return s[r]-s[l-1];} void pre() { for(int i=1;i<=n;i++){ g[i][i]=0; for(int j=i-1;j>=1;j--) g[i][j]=g[i][j+1]+sum(j+1,i)+min(3ll*(i-j)*a[j],sum(j+1,i)); } } void work() { memset(f,0x3f,sizeof(f));f[0]=0; for(int i=1;i<=n;i++) for(int j=0;j<i;j++) f[i]=min(f[i],f[j]+g[i][j+1]+sum(i+1,n)*(4ll*(i-j)-2)); printf("%lld\n",f[n]); } void init() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),s[i]=s[i-1]+a[i]; pre(); } int main() { init(); work(); return 0; }
转载请注明原文地址: https://www.6miu.com/read-800241.html

最新回复(0)