标签:记录 需要 相同 -- efi its 随机 等于 turn
1.抓球
【问题描述】
何老板有N个不透明的箱子,编号1到N。每个箱子里都有若干大小相同的
小球,每个小球上都有一个编号。其中i号箱子里的小球编号是Xi到Yi,也就
是编号Xi,Xi+1,Xi+2,...,Yi-1,Yi的小球都在i号箱子里。
你需要从每个箱子里随机抓一个球出来, 从i号箱子抓出任意一个球的概
率都是1/(Yi-Xi+1)。如果你抓出的N个球中,有大于等于S%的球的编号第一
位都是1(比如: 15, 138, 1196的第一位都是1),那么你将赢得一次与何老
板共进午餐的机会。
问,你赢得美妙午餐的概率有多大?
解:
由于没开LL 掉40....
DP一下即可
code:
//
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define GC getchar()
#define D double
#define maxnn 2100
ll sum[maxnn];
ll n,s;
D f[maxnn][maxnn];
ll res[maxnn];
ll xx[maxnn],yy[maxnn];
double ans=0;
inline ll R() {
char t;
int f=1;
ll x=0;
t=GC;
while(!isdigit(t)) {
if(t=='-') f=-1;
t=GC;
}
while(isdigit(t)) {
x=x*10+t-48;
t=GC;
}
return x*f;
}
int main() {
sum[1]=1;
for(int i=2; i<=20; i++) {
sum[i]=sum[i-1]*10;
}
for(int i=2; i<=20; i++) {
sum[i]=sum[i-1]+sum[i];
}
n=R();
s=R();
ll x,y;
for(int i=1; i<=n; i++) {
x=R();
xx[i]=x;
y=R();
yy[i]=y;
x--;
string s1,s2;
while(x) {
s1.push_back((x%10)+48);
x/=10;
}
ll tmp1=0;
if(s1.back()!='1') {
tmp1+=sum[s1.size()];
} else {
ll remake1=0;
for(int k=s1.size()-2; k>=0; k--) {
remake1=(remake1*10+s1[k]-'0');
}
tmp1+=sum[s1.size()-1]+remake1+1;
}
while(y) {
s2.push_back((y%10)+48);
y/=10;
}
ll tmp2=0;
if(s2.back()!='1') {
tmp2+=sum[s2.size()];
} else {
ll remake2=0;
for(int k=s2.size()-2; k>=0; k--) {
remake2=(remake2*10+s2[k]-'0');
}
tmp2+=sum[s2.size()-1]+remake2+1;
}
res[i]=tmp2-tmp1;
}
f[0][0]=1.0;
for(int i=1; i<=n; i++) {
for(int j=0; j<=i; j++) {
if(j==0) {
f[i][j]=f[i-1][j]*((yy[i]-xx[i]+1-res[i])/1.0/(yy[i]-xx[i]+1));
} else {
f[i][j]=f[i-1][j-1]*(res[i]/1.0/(yy[i]-xx[i]+1))+f[i-1][j]*(((yy[i]-xx[i]+1)-res[i])/1.0/(yy[i]-xx[i]+1));
}
}
}
for(int i=(ceil(n*(s/1.0/100))); i<=n; i++) {
ans+=f[n][i];
}
printf("%.7lf",ans);
}
B
【问题描述】
游戏LOL中的召唤师峡谷地图是一个有n个节点, m条单向道路构成的。最
近,游戏推出了一个新英雄,他拥有特殊技能,对于峡谷中的任意一个节点
x,可以把所有以x为终点的边的权值减少d,同时把所有以x为起点的边的权值
加上d。 现在我们操控新英雄使用他的技能,让所有边的权值的最小值最大。
边的权值>0。
解:
二分+差分约束
看到infinite 我想多了
超过就是infinite...
二分答案跑负环即可
code;
/
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define maxnn 6000
#define inf 1000000000
int dis[maxnn];
int n ,m;
int las[maxnn],en[maxnn],nex[maxnn],tot,le[maxnn];
void add(int a,int b,int c) {
en[++tot]=b;
nex[tot]=las[a];
las[a]=tot;
le[tot]=c;
}
int mapp1[maxnn][maxnn];
#define GC getchar()
inline int R() {
char t;
int f=1;
int x=0;
t=GC;
while(!isdigit(t)) {
if(t=='-') f=-1;
t=GC;
}
while(isdigit(t)) {
x=x*10+t-48;
t=GC;
}
return x*f;
}
int cnt[maxnn];
int mark[maxnn];
int fla=1;
bool spfa(int x,int mid)
{
for(int i=las[x];i;i=nex[i])
{
int v=en[i];
if(dis[v]>dis[x]+le[i]-mid)
{
dis[v]=dis[x]+le[i]-mid;
if(mark[v])return false;
mark[v]=1;
if(!spfa(v,mid))return false;
}
}
mark[x]=0;
return true;
}
bool isok(int mid) {
for(int i=0;i<=n;i++)
{
mark[i]=0;
dis[i]=inf;
}
dis[0]=0;
mark[0]=1;
if(!spfa(0,mid))
return false;
return true;
}
int main() {
while(cin>>n>>m) {
int a,b,c;
memset(las,0,sizeof(las));
tot=0;
for(int i=1; i<=m; i++) {
a=R();
b=R();
c=R();
add(a,b,c);
}
for(int i=1; i<=n; i++) {
add(0,i,0);
}
int l=0,r=110100;
while(l<=r) {
int mid=(l+r)>>1;
if(isok(mid)) {
l=mid+1;
} else {
r=mid-1;
}
}
if(l>10000) {
{
printf("Infinite\n");
continue;
}
}
if(l==0) {
printf("No Solution\n");
continue;
}
printf("%d\n",r);
continue;
}
return 0;
}
C 攻略
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s,128m
问题描述
题目简述:树版[k取方格数]
众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏。今天他得到了一款新游戏《XX半岛》,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景。所有场景和选择支构成树状
结构:开始游戏时在根节点(共通线),叶子节点为结局。每个场景有一个价值,现在桂马开启攻略之神模式,同时攻略k次该游戏,问他观赏到的场景的价值和最大是多少(同一场景观看多次是不能重复得到价值的) “为什么你还没玩就知道每个场景的价值呢?”
“我已经看到结局了。”
解:
长链剖分
考试的时候我居然以为这个东西有后效性..... 然而没有...
或者树形DP记录是哪个儿子传给的 扔进堆里面就行了每次找的时候 更新就行了 ...
或者线段树+dfs序列
记录树上前缀和
每次查找的时候找最长的
然后往上减 去掉子树的影响就行了
code:
//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 400010
#define ll long long
ll las[maxnn],en[maxnn],nex[maxnn],tot;
ll a[maxnn];
ll n,m;
struct node {
ll st,en,l;
};
bool operator <(node a,node b) {
return a.l<b.l;
}
priority_queue<node> Q;
ll ff[maxnn];
#define GC getchar()
inline ll R() {
char t;
int f=1;
ll x=0;
t=GC;
while(!isdigit(t)) {
if(t=='-') f=-1;
t=GC;
}
while(isdigit(t)) {
x=x*10+t-48;
t=GC;
}
return x*f;
}
void add(int a,int b) {
en[++tot]=b;
nex[tot]=las[a];
las[a]=tot;
}
ll f[maxnn],id[maxnn];
void DP(int v,int fa) {
ff[v]=fa;
for(int i=las[v]; i; i=nex[i]) {
int u=en[i];
if(u==fa) continue;
DP(u,v);
if(f[u]>f[v]) {
f[v]=f[u];
id[v]=id[u];
}
}
if(id[v]==0) {
id[v]=v;
}
f[v]+=a[v];
}
int main() {
n=R();
m=R();
for(int i=1; i<=n; i++) {
a[i]=R();
}
int x,y;
for(int i=1; i<n; i++) {
x=R();
y=R();
add(x,y);
add(y,x);
}
DP(1,1);
for(int i=las[1]; i; i=nex[i]) {
int u=en[i];
Q.push(node {u,id[u],f[u]});
}
ll ans=0;
while(m--) {
ans+=Q.top().l;
node r=Q.top();
int d=r.en;
int pos;
pos=d;
while(d!=ff[r.st]) {
for(int i=las[d]; i; i=nex[i]) {
int u=en[i];
if(u==pos) continue;
if(u==ff[d]) continue;
Q.push(node{u,id[u],f[u]});
}
pos=d;
d=ff[d];
}
Q.pop();
}
cout<<ans+a[1];
}
长链剖分:
贪心地选取代价最大的链
//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 400010
#define ll long long
ll las[maxnn],en[maxnn],nex[maxnn],tot;
ll a[maxnn];
ll n,m;
priority_queue<ll> Q;
ll ff[maxnn];
#define GC getchar()
inline ll R() {
char t;
int f=1;
ll x=0;
t=GC;
while(!isdigit(t)) {
if(t=='-') f=-1;
t=GC;
}
while(isdigit(t)) {
x=x*10+t-48;
t=GC;
}
return x*f;
}
void add(int a,int b) {
en[++tot]=b;
nex[tot]=las[a];
las[a]=tot;
}
ll f[maxnn],id[maxnn];
ll son[maxnn];
int topp[maxnn];
void dfs1(int v,int fa) {
for(int i=las[v]; i; i=nex[i]) {
int u=en[i];
if(u!=fa) {
dfs1(u,v);
if(f[u]>f[v]) {
f[v]=f[u];
son[v]=u;
}
}
}
f[v]+=a[v];
}
void dfs2(int v,int fa,int t) {
topp[v]=t;
if(son[v]) {
dfs2(son[v],v,t);
}
for(int i=las[v]; i; i=nex[i]) {
int u=en[i];
if(u==son[v]) continue;
if(u!=fa) {
dfs2(u,v,u);
}
}
}
int main() {
n=R();
m=R();
for(int i=1; i<=n; i++) {
a[i]=R();
}
int x,y;
for(int i=1; i<n; i++) {
x=R();
y=R();
add(x,y);
add(y,x);
}
dfs1(1,1);
ll ans=0;
dfs2(1,1,1);
for(int i=1; i<=n; i++) {
if(topp[i]==i) {
Q.push(f[i]);
}
}
while(m--) {
ans+=Q.top();
Q.pop();
}
cout<<ans;
}
标签:记录 需要 相同 -- efi its 随机 等于 turn
原文地址:https://www.cnblogs.com/OIEREDSION/p/11849741.html