code:
use vector to save every situation's combination, and the length of the left and the right of it(total length, in other word, l1+l2is the final length of used stone)
when there is one stone, keep the left and right 0, and do it until use all the stone(di gui)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
struct node {
double l1, l2;
}nw;
int n;
const int maxn = 65;
double r, w[10], value[maxn], ans;
int vis[maxn];
int num[maxn];
vector<node> adj[maxn];
void dfs(int state) {
if(vis[state]) return;
vis[state] = true;
bool flag = 0;
double l1, l2;
for(int i=state&(state-1); i>0; i=(i-1)&state) {
int j = state^i;
dfs(i);
dfs(j);//quan bu tang kai
for(int s=0; s<num[i]; s++) {
for(int p=0; p<num[j]; p++) {
l2 = value[i]/(value[i]+value[j]);
l1 = value[j]/(value[i]+value[j]);
nw.l1 = max(adj[i][s].l1+l1, adj[j][p].l1-l2);
nw.l2 = max(adj[j][p].l2+l2, adj[i][s].l2-l1);
if(nw.l1+nw.l2<=r){ adj[state].push_back(nw);
num[state]++;
}
}
}
flag = 1;
}
if(!flag) {//zhi sheng yi ge, mei you sheng chang
nw.l1 = nw.l2 = 0;
adj[state].push_back(nw);
num[state]++;
}
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
scanf("%lf%d", &r,&n);
for(int i=0; i<n; i++) {
scanf("%lf", &w[i]);
}
for(int i=0; i<(1<<n); i++) {
value[i] = 0;
adj[i].clear();
for(int j=0; j<n; j++) {
if(i & (1<<j)) value[i] += w[j];
}
}
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
dfs((1<<n)-1);
ans = -1;
for(int i=0; i<num[(1<<n)-1]; i++) {
ans = max(ans, adj[(1<<n)-1][i].l1+adj[(1<<n)-1][i].l2);
}
printf("%.20lf\n", ans);
}
return 0;
}