#include<bits/stdc+.h>
using namespace std;
bool dp[1000][10000];
struct {int val,num}a[1000];
int main()
{
int n,m,i,j,k,tot;
cin>>n>>tot;
memset(dp,false,sizeof(dp));
for(i=0;i<n;++i)
{
cin>>a[i].val>>a[i].num;
}//yidingyaoyoubianjieshuzu1
dp[0][0]=true;
dp[1][0]=true;
for(i=0;i<n;++i)
{
for(j=0;j<=tot;++j)
{
for(k=0;k<=a[i].num&&j-k*a[i].val>=0;++k)
{
dp[i+1][j]|=dp[i][j-k*a[i].val];//k=0 不用可以吗 K=1 用一个可以吗etc
// |=来求bool是这个的核心
}
}
}
cout<<dp[n][m]<<val;
return 0;
}
虽然这样能做出来,但是bool 来这样求有一些浪费,如果我们把每个a[i].left 给计算出来就可以有效地减少复杂度(基础写法)::本蒻鸡只会这么写-,-
然后:挑战程序理由另一种写法:
dp[i+1][j] 前i个数加和到j后第i个数还剩多少 dp[i+1][j]=a[i].num(dp[i][j]>=0) -1 a[i+1][j-a[i].val]<0 dp[i+1][j-a[i]](etc)
//加了一个滚动优化
#include<bits/stdc++.h>using namespace std;
int dp[1000];
struct {int val,num;}a[1000];
int main()
{
int n,m,i,j,k,tot;
cin>>n>>tot;
memset(dp,-1,sizeof(dp));
for(i=0;i<=n;++i)
{
for(j=0;j<=tot;++j)
{
if(dp[j]>=0)dp[j]=a[i].val;//之前已经做好了
else if(dp[j-a[i].val]<=0||j<a[i].val)dp[j]=-1;//从一开头就没有做好或这个比目标大
else dp[j]=dp[j-a[i].val]-1;//用之前的结果
}
}
if(dp[tot]>=0)cout<<"susss"<<endl;
return 0;
}