首页 > 代码库 > hdu5389 Zero Escape DP+滚动数组 多校联合第八场
hdu5389 Zero Escape DP+滚动数组 多校联合第八场
Zero Escape
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 56 Accepted Submission(s): 18
) 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
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 numbered
For example, players
There is two doors, numbered
And there is
For example:
players are
There is only one way to distribute the players: all players get into the door
Given the identifier of every player, please calculate how many kinds of methods are there,
For each test case, the first line contains three integers
Next line contains
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
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<cstring> #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<queue> #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; }
hdu5389 Zero Escape DP+滚动数组 多校联合第八场