解题思路:一开始想到分组背包,不过这种求划分方法数的还不会,母函数也可以AC这道题,不过学得不扎实,给忘了。于是看了别人思路,理解后写得以下代码。感觉很像多重背包,因为每种数量有限嘛,又像分组背包。

AC代码如下:

import java.io.*;
import java.math.*;
import java.util.*;

public class HDU2079 //Main
{
  public static void main(String[] args)
  {
    Scanner cin=new Scanner(System.in);
    int t,i,n,k,j,z;
    int [] dp,object,count;
    dp=new int[50];
    object=new int[10];
    count=new int[10];
    t=cin.nextInt();
    while(t--!=0)
    {
      n=cin.nextInt();
      k=cin.nextInt();
      for(i=1;i<=n;i++) dp[i]=0; //初始化
      dp[0]=1; //边界,即凑成0学分的情况只有一种,就是什么都不选
      for(i=1;i<=k;i++)
      {
        object[i]=cin.nextInt();
        count[i]=cin.nextInt();
      }
      for(i=1;i<=k;i++)
      {
        for(z=n;z>=object[i];z--)
          for(j=1;j<=count[i]&&j*object[i]<=z;j++)  //这边注意和正常01背包的两个循环不一样
            dp[z]+=dp[z-j*object[i]];
      }
      System.out.println(dp[n]);
    }
  }
}