先吐槽一下 學校太不厚道了,省賽掛了就不大給我們時間了,乙個題都不能好好做了
果然線段樹和dp到了zjoi都是怪物
這個題的題目描述非常有誘導性、
對著錯誤的題目做了5天、、、
乙個基站的範圍是指覆蓋它的範圍,而不是它覆蓋的範圍
以下是看錯題部分的思考:
n^2k的dp通過模擬 劃分dp過程 可以發現 它只和上一次選址時 在它左邊的站有關係(利用站無先後的特點、確定j個的右端點)
但我當時在做的時候比題解多想了一步,就是考慮左邊j-1個的右影響範圍,於是乎就有了如下nc的錯誤
但計算花費遇到了諸多麻煩、、如雙變數維護、
所以就請教了yveh學長,然後又拉來了xyx學長
經過漫長的研究,xyx突然大呼:你是不是把題讀錯了;;
然後果然讀錯了,gg。
我說怎麼連題解都看不懂,果然是把題看錯了、、
看對題後就比較清晰了,對於補償基站的情況就可以根據範圍的左右端點確定就可以了
dp就好打了
犯得sb錯誤:
1、重建線段樹一定要把標記清零,
2、n<<2!
小技巧:
對於一些劃分dp,不好取最優質花費,可以用虛擬點的方法,把答案集中到最後乙個多出的點,並將階段總數+1、、
碼:
#include#includeusing namespace std;
#define zz o<<1,l,mid
#define yy o<<1|1,mid+1,r
#define inf 1e9+7
#define n 200005
#includevectoryou[200005];
int max1[n<<2],jia[n<<2],f[n],a,b,l,r,x,op,daan=1e9+7,n,k,j,i,d[n],fw[n],c[n],fq[n],zuo[n],ans;
void up(int o)
void down(int o)
void jian(int o,int l,int r)
jian(zz);
jian(yy);
up(o);
}void zhao(int o,int l,int r)
if(op==2)
return;
} int mid=(l+r)>>1;
if(a<=mid)zhao(zz);
if(b>mid)zhao(yy);
up(o);
}void woc(int now)
else
}you[ans].push_back(now);
//左邊
r=now;
l=1;
zuo[now]=now;
while(l>1;
if(d[mid]>=d[now]-fw[now])
else
} }void dp(int jd)
}
} daan=min(daan,f[n]);
}int main()
d[n+1]=inf; fq[n+1]=inf; fw[n+1]=inf;n++;k++;
for(i=1;i<=k;i++)dp(i);
printf("%d",daan);
}
基站選址 base c cpp pas
有n個村莊坐落在一條直線上,第i i 1 個村莊距離第1個村莊的距離為di。需要在這些村莊中建立不超過k個通訊基站,在第i個村莊建立基站的費用為ci。如果在距離第i個村莊不超過si的範圍內建立了乙個通訊基站,那麼就成它被覆蓋了。如果第i個村莊沒有被覆蓋,則需要向他們補償,費用為wi。現在的問題是,選...
ZJOI2010 基站選址
洛谷題目鏈結 真毒瘤 這個題目耗了我半天。結果是線段樹打錯了。回歸正題 線段樹 dp 首先當然是先考慮樸素 dp 啦,相信你既然都來做這題了,樸素的方程自然不用我多說,設 f i j 表示在前 i 個村莊內,第 j 個基站建在 i 處的最小費用 不考慮 i n 的賠償費用等 方程為 f i j mi...
題解 lg2605 基站選址
題面 設 f i,j 表示前 i 個村莊建立 j 個基站,且第 i 個村莊有基站的最小花費 則有 f i,j min 其中 cost k,i 表示第 i k 個村莊建有基站,中間沒有,所需要補償的費用 發現轉移式中從 j 1 j 我們可以脫去 j 這一維 考慮怎麼計算 cost k,i k i 如果...