hdu5286 dp+递推

本文介绍了一种使用动态规划解决特定数值匹配问题的方法。具体地,将一群人按照其价值分配到两个门中,使得每个门中人员价值总和(通过迭代计算至一位数)与门自身的价值相等。文章提供了详细的算法实现思路与代码。

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

题意:

有n个人,每个人有一个value值,有两扇门A,B分别各有一个value,现在要讲n个人分为两组分别从两个门进入,要求是每组人的value值的和(迭代的求,直至变为一位数字)等于该门的value值,问一共有多少种进入的方法。

分析:

首先我们可以发现,假如能够进去的话,那么所有的人的value值的和刚好等于两扇门的value值的和。或者只进入一个门,也就是只等于一个门的value值。计算这个和的方法就是先真的求出和然后模上9就可以了的。

然后我们可以考虑用dp的方式解决问题了。

dp[i][j]表示的是前i个人中选出一部分人的value值之和等于j的种数。

然后我们可以想到状态转移方程:dp[i][j] = (dp[i-1][j]+dp[i-1][(j+9-a[i])%9]); 

最后我们在n个人中选出一部分人的value值之和等于A门的alue,那剩下的value和就等于B门的value了。


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

#define mod 258280327
int const maxn = 100005;
int dp[maxn][10];
//dp[i][j]表示的是前i个人中的取得的价值为j的方案数
//由于处理的是直接%9,所以价值为9变化为价值为0
int a[maxn];

int main()
{
    int t,n,A,B;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&A,&B);
        int sum = 0 ;
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sum%=9;
        int ans = 0 ;
        if(sum==(A+B)%9)
        {
            dp[0][0] = 1 ;//初始化
            for(int i = 1 ; i <= n ; i++)
            {
                for(int j = 0 ; j <= 9 ; j++)
                {
                    dp[i][j] = (dp[i-1][j]+dp[i-1][(j+9-a[i])%9])%mod;
                }
            }
            if(sum==(B%9))ans++;
            printf("%d\n",(dp[n][A]+ans)%mod);
        }
        else
        {
            if(sum==(A%9))ans++;
            if(sum==(B%9))ans++;
            printf("%d\n",ans);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值