动态规划一直没掌握好,考试的时候没有做出来,看了一些动态规划的资料,建立状态转移方程。
重要的是:状态转移函数的建立,有n个变量,就申请n维的空间。这里的变量是字符串结尾下标i,
以及从【0,i】区间所有数的和,模k的余数j。所有一共有2个变量。所以建立二维数组为dp[i][j]
表示以i结尾,模k为j的最长序列长度。 (看了另外一种写法,该写法中dp[i][j]表示以i结尾,模k为j的开始下标)
动态规划要注意,将原问题转换成,比其规模更小的子问题
写的代码如下,不知道对不对
import java.util.Scanner;
public class Main1{
/**
* 和为k的倍数的最长子串
* @param args
*/
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int k=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++) {
arr[i]=sc.nextInt();
}
//dp[i][j] 表示以arr[i]结尾,所有总和%k,余数为j的字符串最大长度
int[][] dp=new int[n][k];
for(int i=0;i<n;i++) {
for(int j=0;j<k;j++) {
dp[i][j]=0;
}
}
dp[0][arr[0]%k]=1;
int ans=0;
if(arr[0]%k==0) {
ans=1;
}
for(int i=1;i<n;i++) {
arr[i]=arr[i]%k;
for(int j=0;j<k;j++) {
int x=(j+k-arr[i])%k;
if(dp[i-1][x]!=0) {
dp[i][j]=dp[i-1][x]+1;
}
if(j==0 && dp[i][j]>ans)
ans=dp[i][j];
}
if(dp[i][arr[i]]==0)
dp[i][arr[i]]=1;
}
System.out.println(ans);
sc.close();
}
}