T89379 【qbxt】复读警告

T89379 【qbxt】复读警告

题解

这是一道DP题

设置状态  f[ i ][ j ]  前 i 个数中所选数字之和 % key 得 j 的最大方案数

当前我们该选择第 i 个数字了,那么这个数字可以选也可以不选

不选  i  的话方案数直接由 f[ i-1 ][ j ] 转移过来

选  i  的话,选择前 i-1 个数字的时候 % key 的余数是 j-a[ i ]%key ,注意减完之后处理负数的情况

加法分类原理,转移方程:f[ i ][ j ] += f[ i-1 ][ j ] + f[ i-1 ][ t ]

边界条件:f[0][0]=1

ans = f[n][0]

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>

using namespace std;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

const int mod=1e9+7;
int n,key;
int a[1010];
int f[1010][1010];

int main()
{
    n=read();key=read();
    for(int i=1;i<=n;i++)
      a[i]=read();
    
    f[0][0]=1;
    
    for(int i=1;i<=n;i++)
      for(int j=0;j<key;j++)
      {
          int t=j-a[i]%key;
          if(t<0) t=(t+key)%key;
          f[i][j]+=(f[i-1][j]+f[i-1][t])%mod;
      }
    
    printf("%d",f[n][0]%mod);
    
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11237705.html