題目鏈結
讀題意讀了一年。。
題意是將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棵樹,假設每棵樹本身的直徑都...