[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堆的糖果数量

代码:

#include 
using 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)
        {
            f[i][j]=max(f[i-1][j],f[i-1][((j-w)%m+m)%m]+w);
        }
    }
    cout<0]<<endl;
    return 0;
}

end!!!