poj 2454 隨機化(劃片使得選舉勝利)

2021-06-29 14:12:13 字數 1541 閱讀 4281

題意:給出3*k個數,每個數的範圍為[0,1000]。要求將其分為3個長度為k的序列,使得至少有兩個序列的和大於500*k。

思路:第一步的貪心比較好想,從大到小排序後後k個數捨棄不考慮。接下來的題意和雙機排程(和poj2576題意也比較相近,不過那道題揹包能過)有點像,就是讓2k個數分成兩份,每份k個數,使兩組數之和盡可能相近。當然首先想用揹包去做,但是一直wa(為啥不是tle呢??),於是看了題解原來是用隨機才能過,思路見**注釋即可。揹包能夠求出兩組數最相近的情況,複雜度比較高。而隨機只要符合題意就退出迴圈,所以會比揹包更快。

隨機的ac**:

#include #include #include #include #define max(a,b) ((a)<(b)?(a):(b))

#define n 62

struct nodes[n*3],t1[n],t2[n],q;

using namespace std;

int n,sum1,sum2;

bool cmp(struct node a,struct node b)

int main()

sort(s+1,s+1+3*n,cmp);//先從大到小排序,後n個不取必可構成最優

for(i = 1;i<=2*n;i++)else

}while(sum1<=500*n || sum2<=500*n)

for(i = 1;i<=n;i++)

printf("%d\n",t1[i].id);

for(i = 1;i<=n;i++)

printf("%d\n",t2[i].id);

for(i = 2*n+1;i<=3*n;i++)

printf("%d\n",s[i].id);

return 0;

}

揹包的wa:

#include #include #include #define n 62

struct nodes[n*3];

int dp[60005],p[n*2][60005],res1[n],res2[n];

using namespace std;

int n,len1,len2;

bool cmp(struct node a,struct node b)

void print(int d,int x)else

}int main()

sort(s+1,s+3*n+1,cmp);

for(i = 1;i<=2*n;i++)

sum += s[i].w;

dp[0] = 0;

memset(p, 0, sizeof(p));

for(i = 1;i<=sum/2;i++)

dp[i] = n+1;

for(i = 1;i<=2*n;i++)}}

for(j = 0;j=0;i--)

if(dp[i] != n+1)

break;

len1 = len2 = 0;

print(2*n,i);

for(i = 0;i

隨機化演算法

隨機化演算法的主要目的是希望讓隨機發生在演算法上,而不是發生在輸入分布上,這樣的話,沒有特別的輸入會引起我們的演算法的最壞情況。即使你最壞的敵人也無法產生最壞的輸入陣列。因為隨機排列使得輸入次序不再相關。只有在隨機數生成器產生乙個不走運的排列時,隨機演算法才會執行得很差。一.隨機優先順序陣列法 我們...

隨機化搜尋

參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 nn 個深埋在地下的寶藏屋,也給出了這 nn 個寶藏屋之間可供開發的mm 條道路和它們的長度。小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠,也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道路 則相...

簡單隨機化

有乙個挺不錯的 隨機化blog codechef mstones 平面上有 n 個點 x i,y i 保證這 n 個點可以用 7 條直線覆蓋。找出一條直線使得它覆蓋的點最多 30 組 test n leq10 4 x i y i leq1.5 times10 4 每次隨機找兩個點 a,b 判斷它們所...