poj 1189 dp(钉子和小球)

本文介绍了一种基于动态规划的模拟算法,用于解决钉子下落问题。通过为每个钉子分配权重并递归计算指定位置的最终权重,文章详细解释了实现步骤和关键代码。适用于对动态规划及模拟算法感兴趣的学习者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:中文题目看题即可。

思路:将最顶上的钉子给予权值2^n,然后模拟其下落过程,计算最终落到指定位置的权值是多少即可。注意中间任意位置的权值可能来源于三个部分,1、左上位置;2、右上位置;3、如果正上方没有钉子,则来源于正上方。采用递归式的动态规划,因为可能某些钉子的权值不必求出。

#include <stdio.h>
#include <string.h>
#define N 55
char buf[1024];
int s[N][N];
long long dp[N][N],fz,fm;
int n,m;
long long gcd(long long  x,long long y){
    if(!y)
        return x;
    return gcd(y,x%y);
}
long long fun(int x,int y){
    long long res = 0;
    if(dp[x][y])
        return dp[x][y];
    if(x!=y && s[x-1][y])
        res += fun(x-1,y)/2;
    if(y!=1 && s[x-1][y-1])
        res += fun(x-1,y-1)/2;
    if(x>2 && y<x && !s[x-2][y-1])
        res += fun(x-2,y-1);
    return dp[x][y] = res;
}
int main(){
    while(scanf("%d %d\n",&n,&m)!=EOF){
        int i,j,k;
        long long temp;
        memset(s,0,sizeof(s));
        memset(dp,0,sizeof(dp));
        for(i = 1;i<=n;i++){
            gets(buf);
            for(j = 0,k = 1;k<=i;j++)
                if(buf[j]!=' '){
                    if(buf[j] == '*')
                        s[i][k] = 1;
                    k++;
                }
        }
        
        fm = dp[1][1] = (long long)1<<n;
        fz = fun(n+1,m+1);
        temp = gcd(fz,fm);
        if(fz == 0)
            printf("0/1\n");
        else
            printf("%lld/%lld\n",fz/temp,fm/temp);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值