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;
}
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[] 分析其中每个可达到位图的条数, 因为 条数隐藏在位图中 距离可以被求得。
总之这个题目 影响最深就是位图表示状态。
最近看到不少位图的应用 比较强大。。。。。