【转载】随机化贪心

随机化贪心,顾名思义,就是边随机边贪心

这类算法适合解决动态规划类的题目

思想:在贪心原则正确的情况下,随机执行足够多次,就是正解了(涉及到概率学,这里不深究)

不要以为随机到正解几率很小,假设随机到正解的概率为0.1%,我们执行100000次贪心,每次取最优,得到正解的概率是100%

也就是这种贪心也变成了某种意义上的正解

至于例子嘛..

有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,利用所有的木板围成一个三角形使得面积最大。  

计算出这个最大的面积。  

输入格式:  

第1行:一个整数N  

第2..N+1行:每行包含一个整数,即是木板长度。  

输出格式:  

仅一个整数:最大面积乘以100然后舍尾的结果。如果无法构建,输出-1。 

样例输入:  5  1  1  3  3  4 

样例输出:  

692 

我们考虑贪心,贪心原则不难想到,我们尽量让三边的差小,他的面积就大

所以每次将木板加入当前的最短边即可完成贪心

附上随机化贪心代码和测试详情

 1     #include <iostream>  
 2     #include <cstdio>  
 3     #include <cmath>  
 4     #include <cstdlib>  
 5     using namespace std;  
 6     int n,a[41],ans=-1;  
 7     void wash()//随机洗木板顺序  
 8     {  
 9         for(int i=1;i<=n;i++)  
10         {  
11             int t=rand()%n;  
12             a[0]=a[t];  
13             a[t]=a[i];  
14             a[i]=a[0];  
15         }  
16     }  
17     int hl(double aa,double bb,double cc)//海伦公式求面积  
18     {  
19         if(aa+bb>cc&&bb+cc>aa&&aa+cc>bb)  
20         {  
21             double p=(aa+bb+cc)/2;  
22             return trunc(sqrt(p*(p-aa)*(p-bb)*(p-cc))*100);  
23         }  
24         else return -1;  
25     }  
26     void work()//贪心程序  
27     {  
28         int p[3],pos;  
29         p[0]=a[1];p[1]=a[2];p[2]=a[3];  
30         for(int i=4;i<=n;i++)  
31         {  
32             int min=0x7fffffff;  
33             for(int j=0;j<=2;j++)  
34             {  
35                   
36                 if(min>p[j])  
37                 {  
38                     min=p[j];  
39                     pos=j;  
40                 }  
41             }  
42             p[pos]+=a[i];  
43         }  
44         ans=max(ans,hl(p[0],p[1],p[2]));  
45     }  
46     int main()  
47     {  
48         scanf("%d",&n);  
49         for(int i=1;i<=n;i++)  
50         scanf("%d",&a[i]);  
51         for(int i=1;i<=10000;i++)  
52         {  
53             wash();  
54             work();   
55         }  
56           
57         printf("%d\n",ans);  
58         return 0;  
59     }   

一共提交30遍(为了测试概率),AC 30遍

测试点 #1通过该测试点。 得分9,耗时0ms,内存2052kB。
测试点 #2通过该测试点。 得分9,耗时0ms,内存2052kB。
测试点 #3通过该测试点。 得分9,耗时0ms,内存2052kB。
测试点 #4通过该测试点。 得分9,耗时0ms,内存2048kB。
测试点 #5通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #6通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #7通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #8通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #9通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #10通过该测试点。 得分9,耗时15ms,内存2052kB。
测试点 #11通过该测试点。 得分10,耗时31ms,内存2048kB。

实验证明,这是完美的骗分,足足骗了100分。。

猜你喜欢

转载自www.cnblogs.com/luv-letters/p/9188584.html