hdu1354
来源:互联网 发布:python for 无限循环 编辑:程序博客网 时间:2024/06/06 17:12
这个就是二叉树的遍历,那个我看了那么多那么多的题解,看了得有一天了,才看出来,我今天写个带有特别好的注释的
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;double val[10] , l[105] , r[105] , w[10] , ans , room;int n , t[105] , vis[105];int judge(int x){ memset(l , 0 , sizeof(l)); memset(r , 0 , sizeof(r)); memset(val , 0 , sizeof(val)); for(int i = x ; i ; i--){ if(t[i] == -1){//可以分开的节点 int x = i * 2,y = i * 2 + 1; val[i] = val[x] + val[y];//合并 double L = val[y] / val[i]; double R = val[x] / val[i]; l[i] = min(-L + l[x] , R + l[y]);//自己去yy r[i] = max(-L + r[x] , R + r[y]); } else if(t[i]){ val[i] = w[t[i]]; } } double a = r[1] - l[1]; if(a - room < 1e-5) ans = max(ans ,a);}int dfs(int num , int sit ,int use)//num节点编号,sit树中有多少个位置可用,use还有几个挂的使用{ if(use == 0){//到头了 judge(num - 1); return 0; } if(t[num/2] != -1)//祖先不是可延伸的点 dfs(num+1,sit,use); else{ if(use > sit){//如果挂的大于可用位置 t[num] = -1;//改变祖先 dfs(num+1 , sit+1 , use); t[num] = 0;//这个是不成功,然后变回来 } if(sit == 1 && use>1) return 0;//当位置只有一个,但是挂件大于1 for(int i = 1 ; i <= n ; i++){ if(!vis[i]){//没取 vis[i] = 1;//标记 t[num] = i;//挂上i物品 dfs(num+1,sit-1,use-1); vis[i] = 0;//清除标记 t[num] = 0; } } }}int main(){ int tot; scanf("%d",&tot); while(tot--){ scanf("%lf%d",&room,&n); memset(w , 0 , sizeof(w));//w是重量 memset(t , 0 , sizeof(t));//t是放的位置的情况 memset(vis , 0 , sizeof(vis)); for(int i = 1; i <= n ; i++) scanf("%lf",&w[i]); ans = -1; t[1] = -1;//头就是棍子 if(n == 1) printf("%.10lf\n",0.0); else{ dfs(2,2,n);//从第二个节点开始来 if(ans == -1) printf("-1\n"); else printf("%.10lf\n",ans); } } return 0;}
0 0