UVA-1354(ポインタ接点の連携方法‖高効率アルゴリズム複雑度算出なし)
ポインタ接点連合、すなわち各ポインタが実際のnodeを指し、新しいnodeを共同で申請し、新しいポインタで表す.
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
#include <vector>
#include <iostream>
using namespace std;
const int maxn = 7;
typedef struct node *pointer;
struct node{
double weight,leftw,rightw,zhong;
node *left,*right;
node():left(NULL),right(NULL){}
};
int n;
double w[maxn],r;
double res=-1;
double cal_wei(pointer root,int floor){
if(root->left==NULL&&root->right==NULL){
root->leftw=root->rightw=0;
return root->weight;
}
root->leftw=cal_wei(root->left,floor+1);
root->rightw=cal_wei(root->right,floor+1);
return root->leftw+root->rightw;
}
double Min,Max;
void cal_posi(pointer root){
if(root->left==NULL&&root->right==NULL){
return ;
}
root->left->zhong=root->zhong-root->rightw/(root->rightw+root->leftw);
root->right->zhong=root->leftw/(root->rightw+root->leftw)+root->zhong;
Max=max(Max,root->right->zhong);
Min=min(Min,root->left->zhong);
cal_posi(root->left); cal_posi(root->right);
}
void dfs(int num,vector<pointer>& now){
if(num==1){
cal_wei(now[0],0);
now[0]->zhong=0;
Min=10000; Max=-10000;
cal_posi(now[0]);
if(Max-Min>=0&&Max-Min<=r){
res=max(res,Max-Min);
}
return ;
}
<pre name="code" class="html">// , ;
for(int i=0;i<num;i++)
for(int j=0;j<num;j++) if(i!=j){ // , (6*5)*(5*4)*(4*3)*(3*2)*(2*1)*6*10*2 = 10368000;
vector<pointer> next; // ; dfs
pointer x=now[i],y=now[j];
for(int k=0;k<num;k++) if(k!=i&&k!=j) next.push_back(now[k]);
pointer temp=new node();
temp->weight=-1; temp->left=x; temp->right=y;
next.push_back(temp);
dfs(num-1,next);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%lf %d",&r,&n);
vector<pointer> ans;
double x;
for(int i=1;i<=n;i++){
scanf("%lf",&x);
pointer temp=new node();
temp->weight=x;
ans.push_back(temp);
}
if(n==1) {
double t=0; printf("%.9lf
",t); continue;
}
res=-1000;
dfs(n,ans);
if(res==-1000) printf("-1
");
else printf("%.9lf
",res);
}
return 0;
}
下面为高效算法;
用到子集的枚举技巧,node【i】里存的为所有子树姿态下的最优长度;
由于使用
#include <stdio.h> #include <string.h> #include <vector> #define INF 0x3f3f3f3f #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; const int N = 6; const int MAXN = (1<<N); int t, n, i, j, vis[MAXN]; double w[N], sumw[MAXN], r; struct Node { double l, r; Node() {} Node(double ll, double rr) {l = ll; r = rr;} }; vector<Node> node[MAXN]; int bitcount(int x) { if (x == 0) return 0; return bitcount(x/2) + (x&1); } void dfs(int s) { if (vis[s]) return; vis[s] = 1; if (bitcount(s) == 1) { node[s].push_back(Node(0, 0)); return; } for (int l = (s - 1)&s ; l > 0; l = (l - 1)&s) { // 1( 11001) , (2^(bitcount(s)-2)) int r = s^l; dfs(l); dfs(r); for (int i = 0; i < node[l].size(); i++) { for (int j = 0; j < node[r].size(); j++) { double ll =min(-sumw[r] / (sumw[l] + sumw[r]) + node[l][i].l,sumw[l] / (sumw[l] + sumw[r]) + node[r][j].l); double rr =max(sumw[l] / (sumw[l] + sumw[r]) + node[r][j].r,-sumw[r] / (sumw[l] + sumw[r]) + node[l][i].r); node[s].push_back(Node(ll, rr)); } } } } void solve() { double ans = -1; int s = (1<<n) - 1; dfs(s); //printf("%d***
",node[s].size()); node[s].size() ; for (int i = 0; i < node[s].size(); i++) { if (node[s][i].r - node[s][i].l < r) { if (node[s][i].r - node[s][i].l > ans) ans = node[s][i].r - node[s][i].l; } } if (ans == -1) printf("-1
"); else printf("%.10lf
", ans); } int main() { scanf("%d", &t); while (t--) { memset(vis, 0, sizeof(vis)); memset(node, 0, sizeof(node)); scanf("%lf%d", &r, &n); for (i = 0; i < n; i++) scanf("%lf", &w[i]); for (i = 0; i < (1<<n); i++) { sumw[i] = 0; for (j = 0; j < n; j++) { if (i&(1<<j)) sumw[i] += w[j]; } } // solve(); } return 0; }