2014 多校赛 第一场

题目链接

A - Couple doubi

题意:桌上共有 k 个球,第i个球的值为 (1^i+2^i+...+(p-1)^i )mod p

DouBiXp 和 他的女朋友 DouBiNan 轮流拿球,DouBiNan先拿,

所有的球都拿完后,谁手上球的值总和更大谁就赢,

已知 k,p,且p为素数,

若DouBiNan赢输出"YES",否则输出"NO"

分析:DouBiNan先拿,为了赢肯定先拿没有被拿的球中值最大的,

找规律得 每个球的值要么为 0,要么为某个的正数x,且每p-1个球有一个的值为x

那么如果值为x的球个数如果为奇数,则DouBiNan赢,否则赢不了

#include<stdio.h>
int main()
{
    int p,n;
    while(scanf("%d%d",&n,&p)!=EOF){
        if((n/(p-1))%2)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

D - Task

题意:有n台机器和m个任务,第i个任务需要xi时间去完成,且它的难度等级为yi

若第i个任务被完成,可获得收益 500*xi+2*yi

每台机器有一个最大工作时间和能完成的最大难度等级,

若某台机器要完成某任务,则机器的工作时间要不低于任务需要的时间,

机器的难度等级不低于任务的难度等级,

一台机器一天只能完成一次任务,且一个任务只能由一台机器完成

已知每台机器和每个任务的完成时间和难度等级,

求一天能完成的最多的任务数,在此前提下的最大收益

分析:贪心求解

收益只有完成的任务的x,y有关,且x,y越大,获得的收益越大

所以要优先完成x更大的任务,若x相等,要优先完成y大的任务

即任务要按x从大到小排序,若x相等则按y从大到小排序

任务的x按从大到小排序,再给任务匹配机器

当有多台机器符合x条件,那么要选择y满足条件的最小的y,

这样没被用的更大的y的机器,更可能符合完成其他任务

#include<stdio.h>
#include<algorithm>
#define N 100000
using namespace std;
struct stu{
    int time,level;
}task[N+10],machine[N+10];
int cmp(stu a,stu b){
    if(a.time==b.time)
        return a.level>b.level;
    return a.time>b.time;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%d%d",&machine[i].time,&machine[i].level);
        for(int i=1;i<=m;i++)
            scanf("%d%d",&task[i].time,&task[i].level);
        sort(machine+1,machine+1+n,cmp);
        sort(task+1,task+1+m,cmp);
        int j=1,cnt[105]={0},maxm=0;
        long long ans=0;
        for(int i=1;i<=m;i++){
            while(j<=n&&task[i].time<=machine[j].time){
                cnt[machine[j].level]++;
                j++;
            }
            for(int k=task[i].level;k<=100;k++){
                if(cnt[k]){
                    maxm++;
                    ans+=task[i].time*500+task[i].level*2;
                    cnt[k]--;
                    break;
                }
            }
        }
        printf("%d %I64d\n",maxm,ans);
    }
    return 0;
}

E - Peter‘s Hobby

题意:已知昨天天气与今天天气状况的概率关系(wePro),和今天天气状态和叶子湿度的概率关系(lePro)

第一天为sunny 概率为 0.63,cloudy 概率 0.17,rainny 概率 0.2.

给定n天的叶子湿度状态,求这n天最可能的天气情况

分析:概率dp

设 dp[i][j] 表示第i天天气为j的最大概率,

pre[i][j]表示第i天天气最可能为j的前一天天气,

dp[i][j]=max(dp[i-1][k]+log(wePro[k][j])+log(lePro[j][lePos[i]])) (k=0,1,2 表示昨天的天气)

注:由于概率越乘越小,考虑精度原因,用log取对数

log(a*b*c) = log a + log b +log c

#include<stdio.h>
#include<string.h>
#include<math.h>
char Con[5][10]={"Dry","Dryish","Damp","Soggy"};
char We[5][10]={"Sunny","Cloudy","Rainy"};
double lePro[3][4]={0.6,0.2,0.15,0.05,
                  0.25,0.3,0.2,0.25,
                  0.05,0.10,0.35,0.50};  //叶子
double wePro[3][3]={0.5,0.375,0.125,
                    0.25,0.125,0.625,
                    0.25,0.375,0.375};   //天气
double init[3]={0.63,0.17,0.2};
double dp[55][3],pre[55][3];
int n,lePos[55];
void solve()
{
    for(int i=0;i<3;i++)
        dp[1][i]=log(init[i])+log(lePro[i][lePos[1]]);
    for(int i=2;i<=n;i++){
        for(int j=0;j<3;j++){  //今天天气
            double maxp=-1e8;
            int pos=0;
            for(int k=0;k<3;k++){  //昨天天气
                double temp=dp[i-1][k]+log(wePro[k][j])+log(lePro[j][lePos[i]]);
                if(temp>maxp){
                    maxp=temp;
                    pos=k;
                }
            }
            dp[i][j]=maxp;
            pre[i][j]=pos;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int k=1;k<=T;k++){
        printf("Case #%d:\n",k);
        scanf("%d",&n);
        char con[10];
        for(int i=1;i<=n;i++){
            scanf("%s",con);
            for(int j=0;j<4;j++)
                if(strcmp(con,Con[j])==0){
                    lePos[i]=j;
                    break;
                }
        }
        solve();
        double maxp=-1e8;
        int ans[55];
        for(int i=0;i<3;i++)
        if(dp[n][i]>maxp){
            maxp=dp[n][i];
            ans[n]=i;
        }
        for(int i=n-1;i>=1;i--)
            ans[i]=pre[i+1][ans[i+1]];
        for(int i=1;i<=n;i++)
            printf("%s\n",We[ans[i]]);
    }
    return 0;
}

资料扩展:详情点此

本题属于 隐马尔可夫模型

马尔可夫模型:统计模型,每个状态只依赖于之前的状态

马尔可夫模型可用马尔可夫过程描述

我们就为上面的一阶马尔科夫过程定义了以下三个部分:

  状态:晴天、阴天和下雨

  初始向量:定义系统在时间为0的时候的状态的概率

  状态转移矩阵:每种天气转换的概率

  所有的能被这样描述的系统都是一个马尔科夫过程。

隐马尔可夫模型 (Hidden Markov Model) 是一种统计模型,用来描述一个含有隐含未知参数的马尔可夫过程。

包含隐藏状态 (如:天气状态)和 可观状态(如:叶子的湿度)

可以观察到的状态序列和隐藏的状态序列是概率相关的

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-31 20:12:57

2014 多校赛 第一场的相关文章

hdu 4865 Peter&amp;#39;s Hobby(2014 多校联合第一场 E)

Peter's Hobby Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 545    Accepted Submission(s): 237 Problem Description Recently, Peter likes to measure the humidity of leaves. He recorded a leaf

2014多校联合第一场

1001:Couple doubi 暴力打表找规律可知,对于任意的p. (1^i+2^i+...+(p-1)^i)%p={ 非0     ,i%(p-1)==0 0        ,  i%(p-1)!=0 } 所以,结果就很显然了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<c

hdu 4865 Peter&#39;s Hobby(2014 多校联合第一场 E)

题意:已知昨天天气与今天天气状况的概率关系(wePro),和今天天气状态和叶子湿度的概率关系(lePro)第一天为sunny 概率为 0.63,cloudy 概率 0.17,rainny 概率 0.2.给定n天的叶子湿度状态,求这n天最可能的天气情况 分析:概率dp设 dp[i][j] 表示第i天天气为j的最大概率,pre[i][j]表示第i天天气最可能为j的前一天天气,dp[i][j]=max(dp[i-1][k]+log(wePro[k][j])+log(lePro[j][lePos[i]]

hdu 4869 Turn the pokers (2014多校联合第一场 I)

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1265    Accepted Submission(s): 465 Problem Description During summer vacation,Alice stay at home for a long time, with nothing t

hdu 4865 Peter&#39;s Hobby(2014 多校联合第一场 E)

Peter's Hobby Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 545    Accepted Submission(s): 237 Problem Description Recently, Peter likes to measure the humidity of leaves. He recorded a leaf

2015 多校赛 第一场 1007 (hdu 5294)

总算今天静下心来学算法.. Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu’s at the entrance of the tomb while Dumb Zhang’s at the end of it. The tomb is made up of many chambers, the total number is N. And there are M channels connect

2014多校联盟 第一场 Task 贪心

问题 D: Task 题目描述 Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task’s level yi cannot complete this task. If the company complete

HDU 4870 Rating (2014 多校联合第一场 J)(概率)

题意: 一个人有两个TC的账号,一开始两个账号rating都是0,然后每次它会选择里面rating较小的一个账号去打比赛,每次比赛有p的概率+1分,有1-p的概率-2分,当然如果本身是<=2分的也就还是回到0分.然后问最后其中一个账号到达20分时需要打多少次比赛. 思路: 因为每次50分,到达1000分,所以可以看做每次1分,到达20分dp[i]表示i到20的数学期望那么dp[i] = dp[i+1]*p+dp[i-2]*q+1;令t[i] = dp[i+1]-dp[i]则t[i] = (t[i

HDU 4869 Turn the pokers (2014 多校联合第一场 I)

HDOJ--4869--Turn the pokers[组合数学+快速幂] 题意:有m张扑克,开始时全部正面朝下,你可以翻n次牌,每次可以翻xi张,翻拍规则就是正面朝下变背面朝下,反之亦然,问经过n次翻牌后牌的朝向有多少种情况.我们可以把正面朝上理解为1,反面朝上理解为0,那么可以理解为求01串的不同的组合方式有几种. 解题思路:我们可以知道,每张牌假设起始状态都为0,如果翻奇数次,该牌最后的情况是1,如果翻偶数次,该牌的最后情况为0.根据n次翻牌的个数找出1的个数的下限和上限,然后再在这个范围