• BZOJ1835 [ZJOI2010] 基站选址 【动态规划】【线段树】


    题目分析:

    首先想一个DP方程,令f[m][n]表示当前在前n个村庄选了m个基站,且第m个基站放在n处的最小值,转移可以枚举上一个放基站的村庄,然后计算两个村庄之间的代价。

    仔细思考两个基站之间村庄的代价,会发现对于一个村庄,它需要付出代价的时候当且仅当上一个基站控制不到它,下一个基站也控制不到它,所以可以计算使它不付出代价的基站区间,然后在超过这段区间的时候加影响。具体来说就是在线段树上面加w[i]。注意滚动数组。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 25000;
      5 const int inf = 2000000000;
      6 
      7 int n,k;
      8 int d[maxn],c[maxn],s[maxn],w[maxn];
      9 int l[maxn],r[maxn];
     10 
     11 int Minn[2][20100<<2],lazy[2][20100<<2];
     12 
     13 void read(){
     14     scanf("%d%d",&n,&k);
     15     for(int i=2;i<=n;i++) scanf("%d",&d[i]);
     16     for(int i=1;i<=n;i++) scanf("%d",&c[i]);
     17     for(int i=1;i<=n;i++) scanf("%d",&s[i]);
     18     for(int i=1;i<=n;i++) scanf("%d",&w[i]);
     19 }
     20 
     21 void push_down(int dd,int now){
     22     if(Minn[dd][now<<1] != inf){
     23     Minn[dd][now<<1] += lazy[dd][now];
     24     lazy[dd][now<<1] += lazy[dd][now];
     25     }
     26     if(Minn[dd][now<<1|1] != inf){
     27     Minn[dd][now<<1|1] += lazy[dd][now];
     28     lazy[dd][now<<1|1] += lazy[dd][now];
     29     }
     30     lazy[dd][now] = 0;
     31 }
     32 
     33 void push_up(int dd,int now){
     34     Minn[dd][now] = min(Minn[dd][now<<1],Minn[dd][now<<1|1]);
     35 }
     36 
     37 void Modify(int dd,int now,int tl,int tr,int l,int r,int dt){
     38     if(Minn[dd][now] == inf) return;
     39     if(tl >= l && tr <= r){Minn[dd][now]+=dt; lazy[dd][now]+=dt;return;}
     40     if(tl > r || tr < l){return;}
     41     if(lazy[dd][now]) push_down(dd,now);
     42     int mid = (tl+tr)/2;
     43     Modify(dd,now<<1,tl,mid,l,r,dt);
     44     Modify(dd,now<<1|1,mid+1,tr,l,r,dt);
     45     push_up(dd,now);
     46 }
     47 
     48 int Query(int dd,int now,int tl,int tr,int l,int r){
     49     if(tl >= l && tr <= r){return Minn[dd][now];}
     50     if(tl > r || tr < l){return inf;}
     51     if(lazy[dd][now]) push_down(dd,now);
     52     int mid = (tl+tr)/2;
     53     int ans=min(Query(dd,now<<1,tl,mid,l,r),Query(dd,now<<1|1,mid+1,tr,l,r));
     54     push_up(dd,now);
     55     return ans;
     56 }
     57 
     58 vector <int> g[maxn];
     59 void init(){
     60     for(int i=1;i<=n;i++){
     61     int lft = 1,rgt = i;
     62     while(lft < rgt){
     63         int mid = (lft+rgt)/2;
     64         if(d[i]-d[mid] > s[i]) lft = mid+1; else rgt = mid;
     65     }
     66     l[i] = lft; lft = i,rgt = n;
     67     while(lft < rgt){
     68         int mid = (lft+rgt+1)/2;
     69         if(d[mid]-d[i] > s[i]) rgt = mid-1; else lft = mid;
     70     }
     71     r[i] = lft;
     72     }
     73     for(int i=1;i<=n;i++){g[r[i]+1].push_back(i);}
     74 }
     75 
     76 void work(){
     77     init(); n++;int ans=0;
     78     for(int i=1;i<=n;i++){ans += w[i]; Modify(0,1,1,n,i,i,inf);}
     79     for(int j=1,od=1;j<=k+1;j++,od^=1){
     80     memset(Minn[od],0,sizeof(Minn[od]));
     81     memset(lazy[od],0,sizeof(lazy[od]));
     82     int z = c[j];
     83     for(int i=1;i<j;i++) z+=c[i],Modify(od,1,1,n,i,i,inf);
     84     Modify(od,1,1,n,j,j,z);
     85     int pp = 0;
     86     for(int i=1;i<=n;i++){
     87         for(int st=0;st<g[i].size();st++){
     88         Modify(od^1,1,1,n,1,l[g[i][st]]-1,w[g[i][st]]);
     89         pp += w[g[i][st]];
     90         }
     91         if(i <= j) continue;
     92         Modify(od,1,1,n,i,i,min(Query(od^1,1,1,n,1,i-1),pp)+c[i]);
     93     }
     94     ans = min(ans,Query(od,1,1,n,n,n));
     95     }    
     96     printf("%d",ans);
     97 }
     98 
     99 int main(){
    100     read();
    101     work();
    102     return 0;
    103 }
  • 相关阅读:
    SAP ABAP Development Tools in Eclipseのセットアップ
    SET UPDATE TASK LOCAL (ローカル更新 )
    SEARCH(文字の検索)
    OVERLAY(文字の上書き)
    ULINE(插入水平线)
    SKIP(插入空行)
    NO-ZERO(空格补全)
    CONVERT TEXT(转换为可排序格式)
    递归获取子节点
    生活小记
  • 原文地址:https://www.cnblogs.com/Menhera/p/9563897.html
Copyright © 2020-2023  润新知