HDU--5389(01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5389


想到了门与和的关系,但是卡在了分配……上……


天哪,居然没想到这是01背包也是醉了,一直卡在怎么分配那里我去去,一看题解是背包我还以为是多重的,结果01就可以啊……

看了题解才发现,并没有啥发现了呵呵……最近有好几种题都是DP可是思路都偏了没有想到,真是奇了怪了,也不奇怪,可能就是没有很好的理解……


题解还证明了个什么什么东西,但是这题没用这个貌似也能过,用了应该更快。是这样子的:

一个数的数字根只和它mod~9mod 9之后的值有关,只要类似背包就能完成人员分配的计算。

具体证明:数字根=\sum_{i=0}^{w}a_ii=0wai,数字=\sum_{i=0}^{w}10^i*a_ii=0w10iai

数字-数字根=\sum_{i=0}^{w}(10^i-1)*a_ii=0w(10i1)ai,这个数字在modmod 99域下为00



(PS:有些题目给出的范围条件特别重要,很有可能是dp的关键点,要特别注意)



#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <string>
#include <cstdlib>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int mod=258280327;
const int maxd=1e5+5;
int n,A,B;
int dp[maxd][20],a[maxd];

int root(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=x%10;
        x/=10;
    }
    if(ans>9)
        return root(ans);
    else return ans;
}

int main()
{
    int kase;
    scanf("%d",&kase);
    while(kase--)
    {
        scanf("%d",&n);
        scanf("%d%d",&A,&B);
        int sum=0;
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]),sum+=a[i];
        mem(dp,0);
        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])%=mod;
                (dp[i][root(j+a[i])]+=dp[i-1][j])%=mod;
            }
        }
        int id=root(sum),ans=0;
        if(id==root(A+B))
        {
            ans+=dp[n][A];
            if(id==A)
                ans--;
        }
        if(id==A) ans++;
        if(id==B) ans++;

        cout<<ans<<endl;
    }
    return 0;
}

/*

4
3 9 1
1 2 6
3 9 1
2 3 3
5 2 3
1 1 1 1 1
9 9 9
1 2 3 4 5 6 7 8 9

*/


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值