埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L题 K序列
题目链接https://www.nowcoder.com/acm/contest/91/L
思路:由给的数据范围我们可以有两种方法:
1、求总的余数,然后减去最少能凑出来余数的数的个数,一定存在。
2、dp。
(ps:由于数据出的不好,当成字串处理也可以AC)
1 /*
2 dp代码
3 */
4 #include<iostream>
5 #include<string>
6 #include<string.h>
7 using namespace std;
8 int dp[2][10005000]; //滚动数组,状压dp
9 int a[100500];
10 int main(){
11 int n,k;
12 cin>>n>>k;
13 for(int i=1;i<=n;i++){
14 cin>>a[i];
15 a[i]=a[i]%k;
16 }
17 memset(dp,0,sizeof(dp));
18 dp[0][a[1]]=1; //注意这里,先存入一个,不然循环存入的话输出就是0
19 int last=0;
20 for(int i=2;i<=n;i++){
21 last=1-last;
22 for(int j=0;j<k;j++){
23 if(dp[1-last][j]!=0){ //如果为0说明凑不到(j+a[i])%k的余数
24 dp[last][(j+a[i])%k]=max(dp[1-last][(j+a[i])%k],dp[1-last][j]+1);
25 }else{
26 dp[last][(j+a[i])%k]=dp[1-last][(j+a[i])%k];
27 }
28 }
29 }
30 cout<<dp[last][0]<<endl;
31 return 0;
32 }