数据结构与算法实验题6.1 s_sin’s bonus byFZuer
玩家从n 个点n-1 条边的图,从节点1 丢下一个小球,小球将由于重力作用向下落,而
从小球所在点延伸出的每一条边有一个值pi 为小球通过该条边的概率(注意从同一个节点
向下延伸的所有边的pi 的和可以小于1,也可以大于1,并且保证对于单独的一条边不会出
现pi>1 的情况),而对于所有处于最下方的节点(如图红点所示)都可以有一个值vi,代
表玩家可以获得的奖励。现在老板给你这样一张图,之后给你n 个vi 的值,老板希望玩家
可以获得的奖励的期望值最小。(对题目不理解可以参见样例)
Ps:小球不会逆着重力往回滚QAQ。保证所给出的图无重边。
★数据输入
输入第一行为一个正整数N (2 < N < 10000), 表示有n 个节点,编号为1 到N。
接下来N-1 行,每行三个整数a b pi ,表示从a,b 之间有一条路径,经过这条路径的
可能性为pi。
接下来一行为有n 个整数,表示n 个vi 的值(10000>=vi>0)。
★数据输出
输入第一行为一个正整数N (2 < N < 10000), 表示有n 个节点,编号为1 到N。
接下来N-1 行,每行三个整数a b pi ,表示从a,b 之间有一条路径,经过这条路径的
可能性为pi。
接下来一行为有n 个整数,表示n 个vi 的值(10000>=vi>0)。
★数据输出
对于每个询问,输出一行一个数精度要求为.10lf,表示最小的奖励期望值。
输入示例输出示例
7
1 2 0.8
1 3 0.2
2 4 1.0
4 7 1.0
3 5 0.7
3 6 0.3
1 2 3 4 5 6 7
1.2600000000
表示题目看了好久才懂~(最后的n个vi值不一定全部需要用到,根据建立的二叉树,才能确定需要用到多少个)
开始没弄懂父节点数组表示法,按照自己的思路做,写了一个好搞笑的代码,然后又尝试用孩子链表表示法做还是行不通,然后又认真研究了一下父节点数组表示法,看到这个代码,顿时豁然开朗:
#include <iostream>
using namespace std; #define MAX_TREE_SIZE 100
typedef struct //节点结构
{
char data;
int parent; //双亲位置域
}PTNode; typedef struct //树结构
{
PTNode node[MAX_TREE_SIZE];
int count; //根的位置和节点个数
}PTree; //初始化树
void init_ptree(PTree &tree)
{
tree.count=-;
}
//添加节点
void add_ptnode(PTree &tree, PTNode ptnode)
{
tree.count++;
tree.node[tree.count].data = ptnode.data;
tree.node[tree.count].parent = ptnode.parent;
}
//输出树
void print_ptree(PTree &tree)
{
int i;
for(i=;i<=tree.count;i++)
{
cout<<" "<<i<<" "<<tree.node[i].data<<" "<<tree.node[i].parent<<endl;
}
}
//前序遍历
void PreOrder(PTree &tree , int num)
{
for(int i=num; i<=tree.count; i++)
{
if(i == num)
{
cout<<" "<<i<<" "<<tree.node[i].data<<" "<<tree.node[i].parent<<endl;
for(int j=num+ ; j<=tree.count; j++)
{
if(tree.node[j].parent == i)
{
PreOrder(tree , j);
}
}
}
}
}//PreOrder
//树没有中序遍历
//后序遍历
void BackOrder(PTree &tree , int num)
{
for(int i=num; i<=tree.count; i++)
{
if(i == num)
{
for(int j=num+ ; j<=tree.count; j++)
{
if(tree.node[j].parent == i)
{
BackOrder(tree , j);
}
}
cout<<" "<<i<<" "<<tree.node[i].data<<" "<<tree.node[i].parent<<endl; }
}
}//BackOrder int main()
{
FILE *fin=fopen("树的表示法.txt","r"); PTree ptree;
init_ptree(ptree);
PTNode ptnode; while(fscanf(fin,"%c%d",&ptnode.data,&ptnode.parent)!=EOF)
{
add_ptnode(ptree,ptnode);
fscanf(fin,"%c%d",&ptnode.data,&ptnode.parent);
}
//输出树
cout<<"数组下标 节点值 双亲位置"<<endl;
print_ptree(ptree); //前序遍历
//cout<<endl;
//PreOrder(ptree,0); //后序遍历
//cout<<endl;
//BackOrder(ptree,0); fclose(fin);
return ;
}
根据父节点建立的二叉树算法思路,自己写了下面的代码,关键在于后续遍历中,找最后根结点的算法!想了好久,最后还是从数据中找到了规律:
#include<stdio.h> double ans=0.0,a[];
int t=; typedef struct
{
double data; //数据域
int parent; //父节点位置
}PTNode; typedef struct
{
PTNode node[]; //根结构
int count; //根的结点个数
}PTree; PTree ptree;
PTNode ptnode; void add_ptnode(int x1,int x2,double pro)
{
ptree.node[x2].parent=x1; //储存结点的父节点
ptree.node[x2].data=pro*ptree.node[x1].data;//计算权值
} void BackOrder(PTree tree,int num)//后序遍历,递归实现
{
int i,j;
i=num;
if(i<=tree.count)
{
for(j=num+;j<=tree.count;j++)
{
if(tree.node[j].parent==i)//找到该节点的子节点
{
BackOrder(tree,j); //子节点作为新的父节点,向下递归
if((j+i)>tree.count) //分支最低结点算法,判断为(i+j>tree,count)
{
ans+=(a[t]*tree.node[j].data);
t++; } }
} } } int main()
{
int n,i,sit_1,sit_2;
double pro;
scanf("%d",&n);
ptree.count=n;
for(i=;i<=n;i++)
{
ptree.node[i].data=;
} for(i=;i<n-;i++)
{
scanf("%d %d %lf",&sit_1,&sit_2,&pro);
add_ptnode(sit_1,sit_2,pro);
} for(i=;i<n;i++)
{
scanf("%lf",&a[i]);
} BackOrder(ptree,);
printf("%.10lf\n",ans); return ;
}
做题找对算法真的很重要!!!
最终提交代码 修改日期:2013-10-29 15:01:21
:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std; struct PNnode
{
double data;//数据域
int parents;
}; struct PTree
{
PNnode node[];
int count;//节点数
}; PTree ptree;
PNnode pnode;
double ans=0.0,a[],b[];
int t=; int f[]={}; void insert(int x1,int x2,double pro)//插入父节点
{
ptree.node[x2].parents=x1;
ptree.node[x2].data=pro;
f[x1]=;
} /*void search(PTree pt,int n)
{
for(int i=n;i<=pt.count;i++)
{
if(i==n)
{
for(int j=n+1;j<=pt.count;j++)
{
if(pt.node[j].parents==i)
{
pt.node[j].data=pt.node[j].data*pt.node[i].data;
if(f[j]==0)
{
b[t]=pt.node[j].data;
t++;
}
search(pt,j);
}
} }
}
}*/ int main()
{
int n,i,sit_1,sit_2;
double pro;
f[]=;
scanf("%d",&n);
ptree.count=n; for(i=;i<=n;i++)//初始化data
ptree.node[i].data=1.0; for(i=;i<n-;i++)
{
scanf("%d %d %lf",&sit_1,&sit_2,&pro);
insert(sit_1,sit_2,pro);
}
for(i=;i<n;i++)
scanf("%lf",&a[i]); int j=,t=;
for(int q=;q<=ptree.count;q++)
{
if(f[q]==)//最低结点
{
b[t]=1.0;
j=q;
while(j!=)
{
b[t]=b[t]*ptree.node[j].data;
j=ptree.node[j].parents;
//printf("b[%d]=%lf\n",t,b[t]);
}
t++;
}
} //for(i=0;i<t;i++)
// printf("%lf ",b[i]);
//printf("\n");
//for(i=0;i<n;i++)
// printf("%lf ",a[i]);
//printf("\n");
sort(a,a+n);
sort(b,b+t); //for(i=0;i<t;i++)
// printf("%lf ",b[i]);
//printf("\n");
// for(i=0;i<n;i++)
// printf("%lf ",a[i]);
//printf("\n");
for(i=;i<t;i++)
{
ans+=(a[i]*b[t-i-]); } printf("%.10lf\n",ans);
return ;
}
19:33:14
不仅仅是一道题的解决,更重要的是背后的知识。加油吧,少年!
by :FZUer
数据结构与算法实验题6.1 s_sin’s bonus byFZuer的更多相关文章
- 数据结构与算法实验题 6.1 s_sin’s bonus
数据结构与算法实验题 6.1 s_sin's bonus ★实验任务 正如你所知道的 s_sin 是一个非常贪玩的人 QAQ(如果你非常讨厌他请直接从第二段开 始看),并且令人感到非常遗憾的是,他是一 ...
- 数据结构与算法实验题 9.1 K 歌 DFS+剪枝
数据结构与算法实验题 K 歌 ★实验任务 3* n 个人(标号1~ 3 * n )分成 n 组 K 歌.有 m 个 3 人组合,每个组合都对应一个分数,你能算出最大能够得到的总分数么? ★数据输入 输 ...
- 数据结构与算法实验题 4.2 Who is the strongest
数据结构与算法实验题 4.2 Who is the strongest ★实验任务 在神奇的魔法世界,召唤师召唤了一群的魁偶.这些魁偶排成一排,每个魁偶都有一个 战斗值.现在该召唤师有一个技能,该技能 ...
- HDU 3791 二叉搜索树 (数据结构与算法实验题 10.2 小明) BST
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3791 中文题不说题意. 建立完二叉搜索树后进行前序遍历或者后序遍历判断是否一样就可以了. 跟这次的作业第 ...
- 数据结构与算法实验题7.1 M 商人的求救
问题描述:A 国正面临着一场残酷的战争,城市被支持不同领导的两股势力占据,作为一个商人,M先生并不太关心政治,但是他知道局势很严重,他希望你能救他出去.M 先生说:“为了安全起见,我们的路线最多只能包 ...
- 数据结构与算法实验题 7.1 M 商人的求救
问题描述: A 国正面临着一场残酷的战争,城市被支持不同领导的两股势力占据,作为一个商人,M先生并不太关心政治,但是他知道局势很严重,他希望你能救他出去.M 先生说:"为了安全起见,我们的路 ...
- DS实验题 Dijkstra算法
参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...
- 大公司面试经典数据结构与算法题C#/Java解答
几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...
- 【算法】数据结构与算法基础总览(中)——刷Leetcode等算法题时一些很实用的jdk辅助方法锦集
最近重新学习数据结构与算法以及刷leetcode算法题时,发现不少jdk自带的方法可以提升刷题的效率.这些小技巧不仅仅对刷算法题带来便利,对我们平时开发也是很有帮助的.本文以java语言为基础,记录了 ...
随机推荐
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- PyCharm光标变粗的解决办法
pycharm中光标变粗,如下: 此时变成了改写模式,只需要按下键盘的insert键即可
- Session共享的解决方案
http://www.cnblogs.com/xinhaijulan/archive/2010/08/21/1805116.html Session共享的解决方案 1.客户端SessionID值唯一: ...
- 本地计算机 上的 Redis Server 服务启动后停止
服务器上Redis服务安装正常..却启动不了.. 报错 : 本地计算机 上的 Redis Server 服务启动后停止.某些服务在未由其他服务或程序使用时将自动停止. 最后发现是Redis的配置 ...
- [Angularjs]常见api函数
写在前面 在angularjs中提供了一些常用的函数,比如angular.lowercase(),angular.uppercase(),angular.isString(),angular.isNu ...
- 如何配置virtualBox端口转发
1,第一步登陆虚拟主机,安装openssh-server(这一步非常重要,如果不安装,你在宿主机上怎么链接都是连不上的,我当时就犯了这个错误) apt-get install openssh-serv ...
- 密码学初级教程(五)消息认证码MAC-Message Authentication Code
密码学家工具箱中的6个重要的工具: 对称密码 公钥密码 单向散列函数 消息认证码 数字签名 伪随机数生成器 MAC能识别出篡改和伪装,也就是既可以确认消息的完整性,也可以进行认证. 消息认证码的输入包 ...
- 【UEditor】 UEditor整合项目上传资源到阿里云服务器
目录 关于此文 下载源码 JSP代码 Java代码 阿里云jar包引入配置 成功啦! 回到顶部 关于此文 项目中要实现编辑器生成带格式的html文档,存入模板,最后生成html的URL,所以选择了UE ...
- JavaWeb学习总结(五十)——文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- 大数据之sqoopCDH 备份
Sqoop课程笔记 一.概述 1.什么是sqoop? Hadoop的优势在于对数据的存储和处理,相比以前传统的数据库,在处理较较多的数据时,传统数据行业通过提升单机性能以提高处理性能,而且性价比随着性 ...