裸奔 的傻瓜
在通往Ac的路上 蹒跚踱步
import java.util.*;
import static java.lang.Math.*
import static java.util.Arrays.*;
import static java.lang.Integer.*;
import static java.lang.Character.*
public class TwinTowns {
    
int n=0;
    
int[]M = new int[1<<20];
    
    
int count(int mask, int p){
        
return (mask >> 2*p)&3;
    }
    
    
public int[] optimalTwinTowns(int[] x, int[] y, int maxPartners, int minDistance) {
        
int[] res=new int[2];
        n 
= x.length;
        
int i=0,j=0;
        
int oo = 100000000;
        fill(M,oo);
        M[
0]=0;
        
for(i=0;i<n;i++)for(j=i+1;j<n;j++){
            
int d = abs(x[i]-x[j])+abs(y[i]-y[j]); 
            
if(d<minDistance)continue;
            
for(int m =(1<<(2*n))-1;m>=0;m--){
                
if(M[m]==oo)continue;
                
if(count(m,i)>maxPartners-1)continue;
                
if(count(m,j)>maxPartners-1)continue;
                
int nm = m+ (1<<(2*i))+(1<<(2*j));
                
if(d+M[m]<M[nm])M[nm]=M[m]+d;
            }
        }
        
        
for(i=0;i<1<<(2*n);i++){
            
if(M[i]==oo)continue;
            
int cnt = 0;
            
for(j=0;j<n;j++)cnt+=count(i,j);
            cnt
/=2;
            
if(cnt>res[0]){
                res[
0]=cnt;
                res[
1]=M[i];
            }
else if(cnt==res[0&& M[i]<res[1])res[1]=M[i];
        }
        

        
return res;
    }

}

 

 

这个题目就是一道动态规划的题目 题目的大意就是一个无向图选出一组边符合以下条件:

1)每个节点最多可以被选maxP条边

2)选上的每个边至少有minL长度

其中maxP<3。而且无向图中最多有10个顶点。这样我们可以用位图来表示选取边的信息

10*01*………………0110其中每2位表示一个顶点没选中的边的条数 因为maxp<=3的。这样通过位运算我们 就可以很方便更新顶点被选中边的信息。

而数组M[1<<20]则标识的是M[x] 在X的位图情况下最小的花费距离。初始条件是所有的M[]为无限大。 依次选取每条边,更新选取这条边之后对位图产生的影响。首先要分析位图的信息 排产不可达到条件。 典型的动态规划。

 后面根据m[] 分析其中每个可达到位图的条数, 因为 条数隐藏在位图中 距离可以被求得。

总之这个题目 影响最深就是位图表示状态。

最近看到不少位图的应用 比较强大。。。。。

posted on 2008-12-21 21:17  Lyt  阅读(166)  评论(0编辑  收藏  举报