题目连接
https://ac.nowcoder.com/acm/contest/23478/B
题面
思路
我们这里将半块瓜看成一件物品,那么对于每一件物品我们有三种选择方式
- 不选
- 选一个
- 选两个
那么我们直接套一个01背包即可
状态转移方程为:
f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i − 1 ] [ j − a [ i ] ] + f [ i − 1 ] [ j − a [ i ] ∗ 2 ] f[i][j] =f[i-1][j] + f[i-1][j-a[i]] + f[i-1][j-a[i]*2] f[i][j]=f[i−1][j]+f[i−1][j−a[i]]+f[i−1][j−a[i]∗2]
只不过要注意一点就是背包容量不能越界,当然这里也能通过滚动数组优化
代码
#include<bits/stdc++.h>
using namespace std;
//----------------�Զ��岿��----------------
#define ll long long
#define mod 1000000007
#define endl "\n"
#define PII pair<int,int>
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
ll ksm(ll a,ll b) {
ll ans = 1;
for(;b;b>>=1LL) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
ll lowbit(ll x){return -x & x;}
const int N = 1e3+10;
//----------------�Զ��岿��----------------
ll n,m,q,a[N],f[N][N];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
cin>>n>>m;
for(int i = 1;i <= n; ++i) {
cin>>a[i];
a[i]/=2;
}
f[0][0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = 0;j <= m; ++j) {
f[i][j] = (f[i][j] + f[i-1][j]) % mod;
if(j >= a[i])
f[i][j] = (f[i][j] + f[i-1][j-a[i]]) % mod;
if(j >= 2 * a[i])
f[i][j] = (f[i][j] + f[i-1][j-a[i] * 2]) % mod;
}
}
for(int i = 1;i <= m; ++i) {
cout<<f[n][i]<<" \n"[i==m];
}
return 0;
}