正题
题目大意
n个物品,每个物品有cic_ici元,求有多少种方案数使得无法再买另外任何的东西。
解题思路
我们发现其实对于每种方案判断只需要考虑剩下的最小的哪一个,所以我们可以将ccc从小到大排序。然后用fi,jf_{i,j}fi,j表示选择了1∼i−11\sim i-11∼i−1还没有选择时,耗费了j元的方案数。
动态转移:
fi,j=fi+1,j+ci+fi+1,jf_{i,j}=f_{i+1,j+c_i}+f_{i+1,j}fi,j=fi+1,j+ci+fi+1,j
最后我们枚举最小没有选择的是xxx,还剩余resresres元
∑r=0cx−1fn,m−r\sum_{r=0}^{c_x-1}f_{n,m-r}r=0∑cx−1fn,m−r
code
#include<cstdio>
#include<algorithm>
#define N 2010
#define XJQ int(1e7+7)
using namespace std;
int n,m,c[N],f[N][N],ans,t;
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&c[i]),ans+=c[i];if(ans<=m){printf("1");return 0;}ans=0;sort(c+1,c+1+n);//排序f[n+1][0]=1;//初始化for(int i=n;i>=1;i--)for(int j=0;j<=m;j++)f[i][j]=(f[i+1][j]+(j>=c[i]?f[i+1][j-c[i]]:0))%XJQ;//动态转移for(int i=1;i<=n;i++){for(int j=0;j<c[i];j++)if(m-t-j>=0)(ans+=f[i+1][m-t-j])%=XJQ;//计算答案t+=c[i];//减少剩余}printf("%d",ans);
}