博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu5389 Zero Escape DP+滚动数组 多校联合第八场
阅读量:6627 次
发布时间:2019-06-25

本文共 4187 字,大约阅读时间需要 13 分钟。

Zero Escape

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 56    Accepted Submission(s): 18
Problem Description
Zero Escape, is a visual novel adventure video game directed by Kotaro Uchikoshi (you may hear about ever17?

) and developed by Chunsoft.

Stilwell is enjoying the first chapter of this series, and in this chapter digital root is an important factor.
This is the definition of digital root on Wikipedia:
The digital root of a non-negative integer is the single digit value obtained by an iterative process of summing digits, on each iteration using the result from the previous iteration to compute a digit sum. The process continues until a single-digit number is reached.
For example, the digital root of 65536 is 7, because 6+5+5+3+6=25 and 2+5=7.
In the game, every player has a special identifier. Maybe two players have the same identifier, but they are different players. If a group of players want to get into a door numberedX(1X9), the digital root of their identifier sum must be X.
For example, players {
1,2,6}
can get into the door 9, but players {
2,3,3}
can't.
There is two doors, numbered A and B. Maybe A=B, but they are two different door.
And there is n players, everyone must get into one of these two doors. Some players will get into the doorA, and others will get into the door B.
For example:
players are {
1,2,6}
,A=9,B=1
There is only one way to distribute the players: all players get into the door 9. Because there is no player to get into the door 1, the digital root limit of this door will be ignored.
Given the identifier of every player, please calculate how many kinds of methods are there,mod 258280327.

 
Input
The first line of the input contains a single number
T, the number of test cases.
For each test case, the first line contains three integers
n,
A and
B.
Next line contains
n integers
idi, describing the identifier of every player.
T100,
n105,
n106,
1A,B,idi9
 
Output
For each test case, output a single integer in a single line, the number of ways that these
n players can get into these two doors.
 
Sample Input
 
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
 
Sample Output
 
1 0 10 60

  把N个数分成两组。一组加起来是A,一组加起来是B,1<=A,B<=9,也能够全分到同一组。当中加是依照他给的规则加。就是一位一位加。超过一位数了再拆分成一位一位加。

  由于把N个数全加起来再依照那个规则处理和两个两个加是一样的。用dp[i][j][k]表示前i个数分两组。第一组和为j,第二组和为k有多少种,直接依据a[i]和dp[i-1]的情况递推即可了(假设当前和为j,这一位是a[i],若j>a[i],上一位要取的是j-a[i],否则上一位是9-(a[i]-j),尽管和一般加法不一样,但也差不了多少)。这里N非常大,用滚动数组。但我一開始交上去超时,然后发现j和k不须要两重循环。由于前i个数的和是确定的,那么假设j确定了。k也确定了,所以能够先预处理前缀和(按他这样的加法规则的和)。每次依据j直接算出k。这里特别要注意j,k等于0的情况,进行特殊处理。

#include
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;typedef long long LL;const int MAXN=100010;const LL MOD= 258280327;int T,N,A,B;int a[MAXN],sum[MAXN];LL dp[2][10][10];int cal(int i,int j){ if(j>i) return j-i; return 9-(i-j);}int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d",&N,&A,&B); memset(dp,0,sizeof(dp)); sum[0]=0; for(int i=1;i<=N;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; if(sum[i]>=10) sum[i]-=9; } int cur=0; dp[cur][a[1]][0]=1; dp[cur][0][a[1]]=1; for(int i=2;i<=N;i++){ cur=!cur; memset(dp[cur],0,sizeof(dp[cur])); for(int j=0;j<=9;j++){ int k; if(j==0) k=sum[i]; else k=cal(j,sum[i]); if(j==a[i]) dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][0][k])%MOD; if(k==a[i]) dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][j][0])%MOD; if(j>0){ int t=cal(a[i],j); dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][t][k])%MOD; } if(k>0){ int t=cal(a[i],k); dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][j][t])%MOD; } //j==sum[i]时k可能为0 if(j==sum[i]){ k=0; if(j==a[i]) dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][0][k])%MOD; if(k==a[i]) dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][j][0])%MOD; if(j>0){ int t=cal(a[i],j); dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][t][k])%MOD; } if(k>0){ int t=cal(a[i],k); dp[cur][j][k]=(dp[cur][j][k]+dp[!cur][j][t])%MOD; } } } } LL ans=(dp[cur][A][0]+dp[cur][0][B]+dp[cur][A][B])%MOD; printf("%I64d\n",ans); } return 0;}

转载于:https://www.cnblogs.com/clnchanpin/p/7097658.html

你可能感兴趣的文章
为了好好看球,学霸们用深度学习重建整个比赛3D全息图
查看>>
浅谈持续集成
查看>>
【ZH奶酪】如何用textgenrnn处理中文
查看>>
CentOS双机中Docker下安装Mysql并配置互为主从模式
查看>>
OkHttp3源码详解(六) Okhttp任务队列工作原理
查看>>
这样做,轻松在Word中使用MathType
查看>>
VS Code非英语版本连接TFS错误解决方案
查看>>
angular5中使用jsonp请求页面
查看>>
sql in not in 案例用 exists not exists 代替
查看>>
使用newtonjson解决Json日期格式问题
查看>>
WEB前端资源代码:学习篇
查看>>
Nginx安装及配置详解【转】
查看>>
vue2.0 :style :class样式设置
查看>>
测不准原理主要指向微观
查看>>
Android之ExpandableList扩展用法(基于BaseExpandableListAdapter)
查看>>
解决注册表映像劫持
查看>>
怎样获取Web应用程序的路径
查看>>
xcode crash 查找 EXC_BAD_ACCESS 问题根源的方法
查看>>
linux下为php添加mongodb扩展
查看>>
使用java.util.concurrent.ThreadFactory来创建线程
查看>>