ACM-11月5日周日周末训练心得

    昨天打了一场重现赛,一开始看的第11题,这道题大概的题意算是一共有n个兔子在一条数轴上的不同位置,最外面的兔子可以往里面的空隙跳,求最大的跳跃次数,一开始想的是用深搜去做,后来发现其实这个最大的跳跃次数就是相邻兔子的距离和 减去 第一段距离和最后一段距离中的较小值。 

 

for(int i=1;i<n;i++)
{
     int x=a[i]-a[i-1]-1;
     sum+=x;
}
int x=a[1]-a[0]<a[n-1]-a[n-2]?a[1]-a[0]:a[n-1]-a[n-2];
cout<<sum-x+1<<endl;

     然后我看的第八题,这道题的背景还是比较熟悉的,就是三国杀中有主公、忠臣、反贼、内奸,各自获胜的条件跟桌游的一样,每个人的血量为h1、h2、h3、h4,行动顺序为主公反贼忠臣内奸,每次能攻击一个人使他减一滴血,问三个阵营每个阵营获胜的机率,前提:主公和忠臣不会互相攻击,我用的深搜做的,把每一种胜利的结局记录下来加到每个阵营的胜利次数中,最后每一个阵营获胜的机率就是自身胜利次数除以总的获胜次数。

 

   之后这周看的一道数位DP的题目,mountian number,这道题大致的意思就是要求出区间内偶数位大于奇数位的数字的个数,一个比较明白的数位DP,一个注意的是前导零,然后dp[i][j][k] 表示在第i个位置时,前面是j,现在这位是奇数位还是偶数位的数目。

 

int dfs(int pos,int pre,int odd,int zero,int doing)//pos表示当前位置,pre表示前一个数字,odd表示现在位置的奇偶性,zero标识是否还是前导0,doing表示是否枚举到了边界  
{  
    if(pos==-1) return 1;  
    if(dp[pos][pre][odd]!=-1 && !doing)  
        return dp[pos][pre][odd];  
    int end = doing?bit[pos]:9;  
    int ans = 0;  
    for(int i = 0; i<=end; i++)  
    {  
        if(!(i||zero))  
            ans+=dfs(pos-1,9,0,zero||i,doing&&i==end);  
        else if(odd && pre<=i)  
            ans+=dfs(pos-1,i,!odd,zero||i,doing&&i==end);  
        else if(!odd && pre>=i)  
            ans+=dfs(pos-1,i,!odd,zero||i,doing&&i==end);  
    }  
    if(!doing)  
        dp[pos][pre][odd] = ans;  
    return ans;  
}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值