nssl1231-Gift【01揹包,dp】
阿新 • • 發佈:2018-12-17
正題
題目大意
n個物品,每個物品有元,求有多少種方案數使得無法再買另外任何的東西。
解題思路
我們發現其實對於每種方案判斷只需要考慮剩下的最小的哪一個,所以我們可以將從小到大排序。然後用表示選擇了還沒有選擇時,耗費了j元的方案數。 動態轉移: 最後我們列舉最小沒有選擇的是,還剩餘元
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);
}