[Acwing蓝桥杯DP] 1047. 糖果
题目链接:1047. 糖果 - AcWing题库
题目大意:有n堆糖果 每堆糖果有一定的数量不为0 求选n堆中任意堆糖果总和的最大值,且最大值是k的倍数 每堆糖果只能用一次。
数据范围:1<=N<=100
1<=K<=100
分析:这是个经典的背包问题
闫氏DP分析法:
集合:f [ i ][ j ] 表示 : 在前n堆中选总和除以k的余数为j
属性:最大值
方式划分 在前n堆中(1)不选第n堆,(2)选第n堆
状态转移: f [ i ][ j ]=max( f [ i - 1][ j ] ,f [ i - 1][ (( j - w)%k + k)%k//保证为正数] + w ); //w是第i堆的糖果数量
代码:
#includeusing namespace std; const int N=110; int f[N][N]; int n,m; int main() { //初始化 memset(f,-0x3f,sizeof f); f[0][0]=0; cin>>n>>m; for(int i=1;i<=n;i++) { int w; cin>>w; for(int j=0;j =max(f[i-1][j],f[i-1][((j-w)%m+m)%m]+w); } } cout<) { f[i][j] 0]<<endl; return 0; }
end!!!