期望题目

给出几道期望的例题

hdu 4405 

由于种种原因,期望是要逆推的,再知道终点在哪的时候.

/*header*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define rep(i , x, p) for(int i = x;i <= p;++ i)
#define sep(i , x, p) for(int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
#define ll long long
#define mk make_pair
#define fi first
#define se second
using std::min;
using std::max;
using std::swap;
const int maxN = 100000 + 7;

inline int gi() {
    int x = 0,f = 1;char c = gc;
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
}

void print(int x) {
    if(x < 0) pc('-') , x = -x;
    if(x >= 10) print(x / 10);
    pc(x % 10 + '0');
}

struct Node {
    int v , nex;
}Map[maxN];
int head[maxN] , num;
int tot[maxN] , to[maxN];
double f[maxN];

int n , m;

double dfs(int now) {
    if(f[now]) return f[now];
    if(now >= n) return 0.0;
    if(to[now]) return f[now] = dfs(to[now]);
    double p = 1.0 / 6;
    rep(i , 1, 6) f[now] += p * dfs(now + i);
    f[now] += 1.0;
    return f[now];
}

void init() {
    memset(to , 0,sizeof(to));
    rep(i , 0, n + 6) f[i] = 0.0;
}

int main() {
    while(true) {
        n = gi();m = gi();
        if(n == 0 && m == 0) break;
        init();
        for(int i = 1;i <= m;++ i) {
            int u = gi() , v = gi();
            to[u] = v;
        }
        dfs(0);
        printf("%.4lf\n", f[0]);
    }
    return 0;
}
CODE

luogu 1083

f[i][j][0/1]表示前i个教室,已经申请了j个教室,0表示这个时间段要去ci,1表示这个时间段要去di的最小的期望值    

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int maxT = 2000 + 7;
const int maxM = 90000 + 7;
const int maxN = 300 + 7;

int c[maxT],d[maxT],dis[maxN][maxN];
double k[maxT];
double E[maxT][maxT][2];

inline int read() {
    int x = 0,E = 1;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-')E = -1;c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
    return x * E;
}

int main() {
    int n = read() ,m = read(),v = read(),e = read();
    for(int i = 1;i <= n;++ i) c[i] = read();
    for(int i = 1;i <= n;++ i) d[i] = read();
    for(int i = 1;i <= n;++ i) cin >> k[i];
    int u,g,w;
    for(int i = 1;i <= v;++ i) 
        for(int j = 1;j < i;++ j) 
            dis[i][j] = dis[j][i] = 999999999;
    for(int i = 1;i <= e;++ i) {
        u = read(),g = read(),w = read();
        dis[g][u] = dis[u][g] = min(dis[u][g],w);
    }
    for(int k = 1;k <= v;++ k) 
        for(int i = 1;i <= v;++ i) 
            for(int j = 1;j <= v;++ j) 
                if(dis[i][k] + dis[k][j] < dis[i][j])
                    dis[i][j] = dis[j][i] = dis[i][k] + dis[k][j];
    for(int i = 1;i <= n;++ i) 
        for(int j = 0;j <= m;++ j) 
            E[i][j][0] = E[i][j][1] = 999999999;
    E[1][1][1] = E[1][0][0] = 0;
    for(int i = 2;i <= n;++ i) {
        E[i][0][0] = E[i - 1][0][0] + dis[c[i - 1]][c[i]];
        for(int j = 1;j <= min(i,m);++ j) {
            E[i][j][0] = min(E[i - 1][j][1] + k[i - 1] * dis[d[i - 1]][c[i]] + (1 - k[i - 1]) * dis[c[i - 1]][c[i]],E[i - 1][j][0] + dis[c[i - 1]][c[i]]);
               E[i][j][1] = min(E[i - 1][j - 1][1] + k[i - 1] * k[i] * dis[d[i - 1]][d[i]] + k[i - 1] * (1 - k[i]) * dis[d[i - 1]][c[i]] + (1 - k[i - 1]) * k[i] * dis[c[i - 1]][d[i]] + (1 - k[i - 1]) * (1 - k[i]) * dis[c[i - 1]][c[i]],E[i - 1][j - 1][0] + k[i] * dis[c[i - 1]][d[i]] + (1 - k[i]) * dis[c[i - 1]][c[i]]);
        }
    }        
    double minn = 9999999999;
    for(int i = 0;i <= m;++ i) minn = min(min(E[n][i][1],E[n][i][0]),minn);
    printf("%.2lf\n", minn);
    return 0;
}
luogu 1083

bzoj 2134 

因为权值是1,所以此题让求概率 先后俩道题的答案要求一样.

所以就是min(a,b) / a * b.化简一下就是1 / max(a,b)

/*header*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define rep(i , x, p) for(int i = x;i <= p;++ i)
#define sep(i , x, p) for(int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
#define ll long long
#define mk make_pair
#define fi first
#define se second
using std::min;
using std::max;
using std::swap;
const int maxN = 10000000 + 7;

inline int gi() {
    int x = 0,f = 1;char c = gc;
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
}

void print(int x) {
    if(x < 0) pc('-') , x = -x;
    if(x >= 10) print(x / 10);
    pc(x % 10 + '0');
}

int n , A, B, C, a[maxN];
int main() {
    scanf("%d%d%d%d%d",&n,&A,&B,&C,a+1);
    rep(i , 2, n) a[i] = ((long long)a[i-1] * A + B) % 100000001;
    rep(i , 1, n) a[i] = a[i] % C + 1;
    double ans = 0;
    a[n + 1] = a[1];
    rep(i , 1, n) ans += 1.0 / max(a[i] , a[i + 1]);
    printf("%.3lf",ans);
    return 0;
}
bzoj 2134

luogu 1365

分三种情况考虑贡献即可.

#include <iostream>
#include <cstring>
#include <cstdio>
const int maxN = 300000 + 7;
using namespace std;

int L,len;
char s[maxN];

int main(int argc, char const *argv[])
{
    scanf("%d",&len);
    scanf("%s",s + 1);
    double ans = 0,l = 0;
    for(int i = 1;i <= len;++ i) {
        if(s[i] == 'o') {ans += 2.0 * l + 1;l ++;}
        if(s[i] == 'x') {l = 0;}
        if(s[i] == '?') {ans += (2.0 * l + 1) / 2.0;l = (l + 1) / 2;}
    }
    printf("%.4lf", ans);
    return 0;
}
luogu1365

luogu3924 康娜的线段树

的确是线段树,比较好做.直接放上std吧,懒得写线段树了

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7+5;
ll sumv[maxn<<1],a[maxn],s[maxn];
int p[maxn];
namespace io
{
    const int MAXBUF = 1 << 22;
    char B[MAXBUF], *S = B, *T = B;
    #define getc() (S == T && (T = (S = B) + fread(B, 1, MAXBUF, stdin), S == T) ? 0 : *S++)
    template<class Type> inline Type read()
    {
        register Type aa = 0;
        register bool bb = 0;
        register char ch, *S = io::S, *T = io::T;
        for(ch = getc(); (ch < '0' || ch > '9') && ch != '-'; ch = getc())
            ;
        for(ch == '-' ? bb = 1 : aa = ch - '0', ch = getc(); '0' <= ch && ch <= '9'; ch = getc())
            aa = aa * 10 + ch - '0';
        io::S = S, io::T = T;
        return bb ? -aa : aa; 
    }
    int (*F)() = read<int>;
    
    template<> inline double read()
    {
        register double aa, bb;
        register char ch;
        register char *S = io::S, *T = io::T;
        while(ch=getc(),(ch<'0'||ch>'9'))
            ;aa=ch-'0';
        while(ch=getc(),(ch>='0'&&ch<='9'))aa=aa*10+ch-'0';
        if(ch=='.'){bb=1;while(ch=getc(),ch>='0'&&ch<='9')bb*=0.1,aa+=bb*(ch-'0');}
        io::S = S, io::T = T;
        return aa;
    }
    
    char buff[MAXBUF], *iter = buff;
    template<class T>inline void P(register T x, register char ch = '\n')
    {
        static int stack[110];
        register int O = 0;
        register char *iter = io::iter;
        if(!x)*iter++ = '0';
        else
        {
            (x < 0) ? x = -x, *iter++ = '-' : 1;
            for(; x; x /= 10)
                stack[++O] = x % 10;
            for(; O; *iter++ = '0' + stack[O--])
                ;
        }
        *iter++ = ch, io::iter = iter;
    }
    
    inline void putc(register char ch) {*iter++ = ch;}
    
    inline void ouput() {fwrite(buff, 1, iter - buff, stdout), iter = buff;}
}
#define lson o<<1
#define rson o<<1|1
int d=0;
inline void build(int l,int r,int o,int t){
    if(l==r){sumv[o]=a[l];p[l]=t;d=max(d,t);return;}
    int mid=l+r>>1;
    build(l,mid,lson,t+1);
    build(mid+1,r,rson,t+1);
    sumv[o]=sumv[lson]+sumv[rson];
}
inline ll query(int l,int r,int o,int t,ll tt){
    if(l==r){return 1LL*(1LL<<t)*(tt+sumv[o]);}
    int mid=l+r>>1;
    return query(l,mid,lson,t-1,tt+sumv[o])+query(mid+1,r,rson,t-1,tt+sumv[o]);
}
ll gcd(ll a,ll b){
    while(b){
        ll r=a%b;a=b;b=r;
    }
    return a;
} 
int main(){
    using io::P;
    int (*F)()=io::read<int>;
    int n=F(),m=F(),yyy=F();
    for(register int i=1;i<=n;++i)a[i]=F();
    build(1,n,1,1);
    ll ans=query(1,n,1,d-1,0),y=1LL<<(d-1);
    ll yy=gcd(y,yyy);yyy/=yy;y/=yy;
    for(register int i=1;i<=n;++i)s[i]=s[i-1]+1LL*(((1LL<<p[i])-1)<<(d-p[i]));
    while(m--){
        int l=F(),r=F(),x=F();
        ans+=(s[r]-s[l-1])*x;
        P(ans/y*yyy);
        io::ouput();
    }
}
View Code

bzoj 2134 
bzoj 2134 

#include<i

ostream>#include<cstring>#include<cstdio>constint maxN = 300000 + 7; usingnamespacestd; int L,len; char s[maxN]; intmain(int argc, charconst *argv[]){ scanf("%d",&len); scanf("%s",s + 1); double ans = 0,l = 0; for(int i = 1;i <= len;++ i) { if(s[i] == 'o') {ans += 2.0 * l + 1;l ++;} if(s[i] == 'x') {l = 0;} if(s[i] == '?') {ans += (2.0 * l + 1) / 2.0;l = (l + 1) / 2;} } printf("%.4lf", ans); return0; }

猜你喜欢

转载自www.cnblogs.com/gzygzy/p/10259109.html