題目:poj 2152 fire
我想說的:以前做揹包的題目做多了,腦子形成了一種就是所有動態規劃就是在陣列上進行等一些固定的思想。結果最近在做一些題目的時候,感覺無從下手,想好久都沒結果。非常慶幸自己做了這類題目,讓我從那種狹隘的思想中做出來。以後就要根據實際情況研究狀態了。
題意:有n個城市,每兩個城市只有一條路連線,(所以可以當成是一顆樹)。現在要建設一些防火站,使每個城市都可以被覆蓋。每個城市的屬性是:在本城市建防火站的價錢和不在本城市建設的話,所依賴的別的防火站的最長距離。然後是n-1條路,和這條路的長度。現在問在覆蓋所有城市的前提下的最少**。
解題:首先要說的是,感覺這個題目很難,自己想了一天,然後看了一天的解題報告,包括國家集訓隊**,陳啟峰2023年的《
一張一弛,解題之道 ——「約制、放寬」方法在解題中的應用》,結果還是不明白,最後只有對著講解,看**,模擬,最後又花費了一上午的時間理解了乙個大概,現在就用自己理解的來說一下吧。
dp[i][j]:表示以i為根的子樹裡修建一些消防站,並在節點j處修建一消防站,i的負責站必須是j;
best[i]:表示表示以i為根的子樹的所有節點都有負責站的最小花費。
dist[i]:表示i到x的距離(每換換乙個節點,都要再求一次dist)。
狀態狀態轉移方程:dp[i][j]=w[j]+sum(min(best[y],dp[y][j]-w[i]))(y是i的所有孩子);
哎!不是很理解,所有也就能寫這麼多了,在網上搜了乙個詳細的,大家可以參考這個poj 2152 fire。
個人**:
#include #include #include #include using namespace std;
#define n 1010
#define m (1<<30)
struct citycity[n];
struct lianjie
};vector tree[n];
int num,dist[n],best[n],dp[n][n];
void init()
{ scanf("%d",&num);
int i,u,v,l;
for(i=1;i<=num;i++) tree[i].clear();
for(i=1;i<=num;i++) scanf("%d",&city[i].w);
for(i=1;i<=num;i++) scanf("%d",&city[i].d);
for(i=1;icity[key].d) dp[key][i]=m;
else
{dp[key][i]=city[i].w;
for(j=0;j>t;
while(t--)
{init(); dfs(1,0);
cout<
一道感覺很難受的題QAQ
這道題我確實是不想寫的,但感覺既然感覺被坑了,還是寫了吧qaq,沒想到運算子能用的這麼多 d ou time limit 1000msmemory limit 131072kb64bit io format lld llu submit status practice hpu 1189 descri...
POJ 3630 一道簡單的字典樹
刷刷更健康.這道題掌握了字典樹難度不大.關鍵是如何判斷是否有串是某串的字首 這個我是用個陣列記住每個字串末尾節點的位置 做的時候是經過乙個點就 1.最後只要判斷所有的末尾節點是不是都為1 如果都為1當然就說明沒有誰為誰的字首字串 反之就是有串是某串的字首字串 program includeusing...
Two Matchings 有趣的一道簡單dp
當乙個數列在計算的時候,出現了多種狀態的時候,不能只顧頭尾不管中間,這時候需要用的dp去慢慢的選擇每一步中最優的狀態!include using namespace std typedef long long ll const int mx 200020 ll dp mx ll a mx ll he...