(信息学奥赛一本通 1299)糖果#线性动态规划#

题意:给出n个数,找出若干个数,使它们的和为k的倍数,并输出最大的数。

状态转移方程:f[i][j]表示前i个数%k=j的总数。

f[i][j]=max(f[i-1][j],f[i-1][tmp]+a[i]);

tmp=(k+j-a[i]%k)%k(避免负数)

第一种情况不选第i个数,第二种情况为选这个数时的最优值

(当然要满足tmp=0或者f[i-1][tmp]有最优值)

#include
#include
using namespace std;
int a[101],n,k,f[101][101];
int main(){
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
for (int j=0;j f[i][j]=f[i-1][j];//不选的情况
int tmp=(k+j-a[i]%k)%k;//避免负数
if (!tmp||f[i-1][tmp]) f[i][j]=max(f[i][j],f[i-1][tmp]+a[i]);//推导
}
printf("%d",f[n][0]); //选n个数并且余数为0的最优值。

        return 0;
}

你可能感兴趣的:(线性dp)