洛谷P2503 HAOI2006 模擬退火

2021-09-25 20:54:11 字數 1760 閱讀 3990

題目鏈結

讀題意讀了一年。。

題意是將n個數分成m組,將每個組的求乙個sum。

計算m個sum的方差。求最小的方差。

思路:先考慮連續選m個分組求最小方差,很容易想到dp。

dp[i][j]表示前i個數分成j組最小的花費。

狀態轉移就是dp[

i][j

]=mi

n(dp

[i][

j],d

p[k]

[j−1

]+(p

re[i

]−pr

e[k]

−sum

/n))

(k

j<=m

)dp[i][j] = min(dp[i][j], dp[k][j-1]+(pre[i]-pre[k]-sum/n))(kdp

[i][

j]=m

in(d

p[i]

[j],

dp[k

][j−

1]+(

pre[

i]−p

re[k

]−su

m/n)

)(kj<=m

)pre[i]表示字首和,sum表示陣列總和(因為均值一定:sum/n)

在考慮模擬退火,隨機交換兩個數,如果交換之後使能量減少,就可以交換,否則以一定機率交換。。套一套板子就行了。

#pragma gcc optimize(2)

#include

using namespace std;

#define ft first

#define sd second

#define all(c) ((c).begin()), ((c).end())

#define mp(a, b) make_pair(a, b)

#define pb(x) push_back(x)

const

int maxn =

1e5+5;

typedef

long

long ll;

const ll mod =

1e9+7;

int case =1;

int n, m;

double a[maxn]

, pre[maxn]

;double res =

1e18

, t, sum;

double dp[

100]

[100];

const

double delta =

0.993

;doubled(

double x)

double

cal_energy()

}}return dp[n]

[m];

}void

simulate_anneal()

elseif(

exp(

-new_delta/t)

*rand_max >

rand()

) nowres = now;

else

swap

(a[x]

, a[y]);

t *= delta;

}// for(int i = 1; i <= n; i++)

// }

}void

solve()

intmain()

return0;

}

題解 P2503 HAOI2006 均分資料

luogu 模擬退火套dp 關於基礎的模擬退火歡迎來踩blog 正確時交兩次a兩次 種子隨機 woc這不是mo你退火的風格啊嘎嘎嘎 看我平衡點那篇博文的辛酸史。這道題其實就是連續分組,用模擬退火打亂不就隨機了嗎?然後就只有計算稍微難一點了 描述對乙個初二蒟蒻相當不友好啊喂!最後放出 includeu...

洛谷P2504 HAOI2006 聰明的猴子

在乙個熱帶雨林中生存著一群猴子,它們以樹上的果子為生。昨天下了一場大雨,現在雨過天晴,但整個雨林的地表還是被大水淹沒著,部分植物的樹冠露在水面上。猴子不會游泳,但跳躍能力比較強,它們仍然可以在露出水面的不同樹冠上來回穿梭,以找到喜歡吃的果實。現在,在這個地區露出水面的有n棵樹,假設每棵樹本身的直徑都...

洛谷 P2504 HAOI2006 聰明的猴子

在乙個熱帶雨林中生存著一群猴子,它們以樹上的果子為生。昨天下了一場大雨,現在雨過天晴,但整個雨林的地表還是被大水淹沒著,部分植物的樹冠露在水面上。猴子不會游泳,但跳躍能力比較強,它們仍然可以在露出水面的不同樹冠上來回穿梭,以找到喜歡吃的果實。現在,在這個地區露出水面的有n棵樹,假設每棵樹本身的直徑都...