国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

sgu148 B-station(Bomb)

2019-11-14 10:38:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

題目

        在離著名的國(guó)家Berland不遠(yuǎn)的地方,有一個(gè)水下工作站。這個(gè)工作站有N層。已知:是第層裝有Wi的水,最多可以容納Li的水,恐怖分子炸毀第i的代價(jià)是Pi。第i層一旦被炸毀,該層所有的水都將傾瀉到第i+1層。如果某一層的水量超過(guò)了它的容量(即Li),那么該層就將自動(dòng)被毀壞,所有的水也會(huì)傾瀉到下一層。

        Pivland的恐怖分子想要用最少的錢毀掉第N層,現(xiàn)在他雇傭你來(lái)計(jì)算,需要炸毀哪些層。

 

 

輸入

 

      第一行有一個(gè)自然數(shù)N(1<=n<=15000)。接下來(lái)的N行,每行3個(gè)整數(shù)Wi, Li, Pi(0<=Wi,Li,Pi<=15000)。

 

輸出

 

     輸出需要炸毀的層的編號(hào)。

Solution1:小根堆+枚舉。

從下往上推的話,f[i]是從i層開始炸毀的代價(jià)如果炸毀i-1,且s[i]-s[i-2]>l[i],那么從第i-1層開始炸毀的代價(jià)是f[i]+c[i-1]-c[i]; 從第k層開始炸毀時(shí)只要將第i(k<i<=n)層里(s[i]-s[k-1]>l[i]) 層里之前算作炸毀的層的c[i]減去,并標(biāo)記沒(méi)被炸毀.用優(yōu)先隊(duì)列優(yōu)化的話將快很多,只要將當(dāng)前炸毀的層入隊(duì),當(dāng)滿足s[i]-s[k-1]>l[i]時(shí),出隊(duì)并減去c[i];

#include <cstdio>  #include <queue>  #include <utility>  using namespace std;  typedef pair<int,int> aii;const int maxx = 15000+10, INF = 2e9;  PRiority_queue< aii > heap;int n;int ans = INF,flag = 0,sum = 0,Sum = 0; int v[maxx],s[maxx],c[maxx];int pre[maxx];bool hash[maxx];int main()   {  //	freopen("Bstation.in","r",stdin);//	freopen("Bstation.out","w",stdout);	    scanf("%d",&n);      	for(int i=n;i>=1;i--)       {          scanf("%d%d%d",&s[i],&v[i],&c[i]);            pre[i] = pre[i+1]+s[i];      }       	for(int i=1;i<=n;i++)      {          for(;!heap.empty() && heap.top().first>pre[i+1]; heap.pop())              sum -= heap.top().second;        heap.push(make_pair(pre[i]-v[i], c[i]));          sum+=c[i];          if(ans>sum)          {              ans = sum;              flag = i;             }      }        	for(int i=flag;i>=1;i--)      {          Sum += s[i];        if(Sum>v[i])              hash[i] = true;       }          for(int i=flag;i>=1;i--)          if(!hash[i])              printf("%d/n", n-i+1);      return 0;  }Solution2:類似二分查找的算法。

之前做過(guò)B-station,是用堆的方法。奈何考場(chǎng)碰到此題時(shí)早已把此方法忘得一干二凈/捂臉。所以迫不得已,強(qiáng)行自己創(chuàng)造了

一個(gè)類似二分查找的方法來(lái)通過(guò)此題防止爆零…咳咳咳,這個(gè)方法大致是這樣的。讀入時(shí)首先處理(由于本人個(gè)人習(xí)慣原因,把最高

層叫做第一層。要炸的叫最底層)之后用sum[i]表示重量的前綴和,用val[i]表示炸該層的費(fèi)用。之后把每層放入結(jié)構(gòu)體。關(guān)鍵字:

d,l,w,id,need(need保存的是壓毀此層時(shí)至少毀掉的最高層。換句話說(shuō),設(shè)i層的need為need[i],只要從need[i]到i-1之間

所有層都已毀壞,第i層就會(huì)直接被壓毀。而這個(gè)need怎么求呢?假設(shè)第i層的need[i]為T,則有sum[i]-sum[T-1]>l[i]。經(jīng)變形得

到sum[T-1]<sum[i]-l[i]。這時(shí)候,因?yàn)閟um單調(diào)遞增,可知sum[T]>=sum[i]-l[i]。所以可以用lower_bound函數(shù)直接找出

need[i]。接下來(lái)我們要做的是將結(jié)構(gòu)體依照need進(jìn)行排序。然后創(chuàng)建一個(gè)vector<int> sale[]的數(shù)組。sale[i]中存以此層作為最

高層時(shí)可以壓毀的層的編號(hào)。之后就直接自底往上開始枚舉最高層。每次枚舉時(shí)首先tmp += val[i](都考慮直接炸掉),之后在

sale[i]中進(jìn)行查找,如果有編號(hào)在i層和底層之間,也就是sale[i][j]>i,則tmp-=val[sale[i][j]]。(說(shuō)明以i為最高層時(shí)此層不用

炸)。每次枚舉過(guò)后比較tmp與Ans。最終就能得到答案。//考試時(shí)做了幾個(gè)小時(shí),生無(wú)可戀.jpg。

#include <cstdio>#include <algorithm>#include <queue>#include <vector>using namespace std;const int maxx = 100000 + 100;struct Edge{    int id;    int d;    int l;    int w;    int need;}Edges[maxx];long long sum[maxx],val[maxx],cost[maxx];long long Ans = 1e9 + 100,tmp;int n;vector <int> sale[maxx];bool cmp(Edge a,Edge b){    if(a.need != b.need)    return a.need<b.need;    else    return a.id<b.id;}int main(){//    freopen("Bomb.in","r",stdin);//    freopen("Bomb.out","w",stdout);        scanf("%d",&n);        for(int i=n;i>=1;i--){        scanf("%d%d%d",&Edges[i].d,&Edges[i].w,&Edges[i].l);        val[i]=Edges[i].d;        Edges[i].id = i;    }        for(int i=1;i<=n;i++)        sum[i]=sum[i-1]+Edges[i].w;        for(int i=1;i<=n;i++){        int T = lower_bound(sum,sum+i,sum[i]-Edges[i].l)-sum;        if(T>0) Edges[i].need = T;        else Edges[i].need = 0;    }        sort(Edges+1,Edges+n+1,cmp);        for(int i=1;i<=n;i++)        sale[Edges[i].need].push_back(Edges[i].id);        for(int i=n;i>=1;i--){        tmp += val[i];        for(int j=0;j<sale[i].size();j++){            if(sale[i][j]>i)            tmp -= val[sale[i][j]];        }        Ans = min(Ans,tmp);    }    printf("%d",Ans);    return 0;}看來(lái)做過(guò)的題目還是要好好學(xué)懂啊QvQ。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安泽县| 太仓市| 嘉善县| 南汇区| 淅川县| 崇礼县| 张北县| 简阳市| 青浦区| 太原市| 嘉善县| 淄博市| 桂平市| 正镶白旗| 布尔津县| 抚顺县| 响水县| 兰西县| 桃园县| 东安县| 汪清县| 宾阳县| 奉新县| 枣强县| 丰城市| 大丰市| 屯留县| 吉林市| 贵州省| 遂宁市| 香格里拉县| 胶南市| 乌兰察布市| 精河县| 泰兴市| 盐亭县| 柏乡县| 修武县| 信阳市| 海安县| 大竹县|