hdu5389(DP)

来源:互联网 发布:剑网3更新网络中断 编辑:程序博客网 时间:2024/06/05 06:46

题意:

给出n个人的id,有两个门,每个门有一个标号,我们记作a和b,现在我们要将n个人分成两组,进入两个门中,使得两部分人的标号的和(迭代的求,直至变成一位数,我们姑且叫做求“和”操作~)分别等于a和b,问有多少种分法。


思路:

很容易想到,如果能找到满足题意的解,一定满足a和b的和等于n个人的标号的和,所以我们只需要判断n个人的标号组成a的情况有多少(或者只判断b,一样),同时还要注意可以把n个人都分给a,或者都分给b,这样也是满足的。

具体的细节都在代码里了,一看应该就能懂~~


代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=100005;#define mod 258280327int SUM(int x,int y){int tmp=x+y;int ans=tmp%9;if(ans==0)return 9;return ans;}int num[maxn];int dp[maxn][10];int main(){int t;scanf("%d",&t);while(t--){int n,a,b;scanf("%d%d%d",&n,&a,&b);int sum=0;for(int i=1;i<=n;i++){scanf("%d",&num[i]);sum=SUM(sum,num[i]);}memset(dp,0,sizeof dp);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][SUM(num[i],j)]+=dp[i-1][j];dp[i][j]%=mod;dp[i][SUM(num[i],j)]%=mod;}}int ans=0;if(SUM(a,b)==sum){ans+=dp[n][a];if(a==sum)ans--;}if(a==sum)ans++;if(b==sum)ans++;printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击