算法分析
01背包问题
注意:由于都需要取模操作,并不是单调操作,因此不能从大到小简化到1
维
时间复杂度 $O(nk)$
参考文献
蓝桥杯辅导课
Java 代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int N = 110;
static int INF = 0x3f3f3f3f;
static int n;
static int k;
static int[][] f = new int[N][N];//从前i个物品中选,且总体积模k恰好是j的最大值
static int mod(int x,int y)
{
return ((x % y) + y) % y;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
k = scan.nextInt();
for(int i = 0;i <= n;i ++)Arrays.fill(f[i], -INF);
f[0][0] = 0;
for(int i = 1;i <= n;i ++)
{
int v = scan.nextInt();
for(int j = 0;j < k;j ++)
{
f[i][j] = f[i - 1][j];
f[i][j] = Math.max(f[i][j], f[i - 1][mod(j - v,k)] + v);
}
}
System.out.println(f[n][0]);
}
}
另外我也想请教一下为什么这个转移方程的取余问题,f[i][j] = Math.max(f[i][j], f[i - 1][mod(j - v,k)] + v);
取余的话是只对 f[i - 1][mod(j - v,k)] 也就是i-1层的总和取余再加上v,为什么不能对v也一起取余了呢?
return ((x % y) + y) % y;为什么取余的时候要这么写呢?
想问下你画图用什么软件哈
系统自带的画图软件