HDU--5389(01背包)

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

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

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

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

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

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

具体证明:数字根=\sum_{i=0}^{w}a_i∑?i=0?w??a?i??,数字=\sum_{i=0}^{w}10^i*a_i∑?i=0?w??10?i???a?i??

数字-数字根=\sum_{i=0}^{w}(10^i-1)*a_i∑?i=0?w??(10?i???1)?a?i??,这个数字在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

*/

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

时间: 2024-12-15 06:41:45

HDU--5389(01背包)的相关文章

poj3211Washing Clothes(字符串处理+01背包) hdu1171Big Event in HDU(01背包)

题目链接: poj3211  hdu1171 这个题目比1711难处理的是字符串如何处理,所以我们要想办法,自然而然就要想到用结构体存储,所以最后将所有的衣服分组,然后将每组时间减半,看最多能装多少,最后求最大值,那么就很愉快的转化成了一个01背包问题了.... hdu1711是说两个得到的价值要尽可能的相等,所以还是把所有的价值分为两半,最后01背包,那么这个问题就得到了解决.. 题目: Washing Clothes Time Limit: 1000MS   Memory Limit: 13

Robberies hdu 2955 01背包

Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10933    Accepted Submission(s): 4049 Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that

hdu 1203 01背包 I need a offer

hdu 1203  01背包  I need a offer 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1203 题目大意:给你每个学校得到offer的概率以及花费,给定money,求得到至少一份offer的最大概率. 简单的01背包 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 double

hdu 1864 01背包 最大报销额

http://acm.hdu.edu.cn/showproblem.php?pid=1864 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的选拔 最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18562    Accepted Submission(s): 5459

HDU 2639 01背包(分解)

http://acm.hdu.edu.cn/showproblem.php?pid=2639 01背包第k优解,把每次的max分步列出来即可 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct Node 6 { 7 int price; 8 int val; 9 }node[1005]; 10 int main() 11 { 12 i

HDU 2126 01背包(求方案数)

Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1886    Accepted Submission(s): 699 Problem Description When the winter holiday comes, a lot of people will have a trip. Genera

HDU 2639 01背包求第k大

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3718    Accepted Submission(s): 1903 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

HDU1171_Big Event in HDU【01背包】

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 24321    Accepted Submission(s): 8562 Problem Description Nowadays, we all know that Computer College is the biggest department

HDU 2602 (0-1背包)

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 35815    Accepted Submission(s): 14753 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bon

[HDOJ1171]Big Event in HDU(01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1171 许多有价值的物品,有重复.问如何将他们分成两堆,使两堆价值之差最小. 对价值求和,转换成01背包,做一次,相当于一堆选物品使得最接近一半.然后这个结果和用价值和作差的结果就是两堆的价值,此时价值只差最小. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <c