【链接】 我是链接,点我呀:)
【题意】
在这里输入题意
【题解】
二维费用背包。
f[i][j][k]
前i个人,写了j行,bug不超过k的方案数。
可以把每个人看成是一个物品。
它可以无限拿。然后花费为 1行代码和a[i]个bug
(拿几个第i个人就相当于v[i]等于几.
就变成一个二维的完全背包了
直接用二维费用背包的方案数求法求得就好
两维的写法比三维的写法简单。。直接顺序更新就可以了
(顺序更新)
【代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 500;
int n,m,b,mod;
int f[N+10][N+10],a[N+10];
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "r", stdin);
#endif
cin >> n >> m >> b >> mod;
for (int i = 1;i <= n;i++) cin >> a[i];
f[0][0] = 1;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
for (int k = a[i];k <= b;k++)
f[j][k] = (f[j][k]+f[j-1][k-a[i]])%mod;
int ans = 0;
for (int i = 0;i <= b;i++) ans =(ans + f[m][i])%mod;
cout<<ans<<endl;
return 0;
}
【附:三维写法】
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define maxn 505
using namespace std;
int dp[2][maxn][maxn];
int ai[maxn];
int main()
{
int n,m,b,mod;
while(scanf("%d%d%d%d",&n,&m,&b,&mod) == 4){
memset(dp,0,sizeof(dp));
for(int i = 0;i <= 1;++i)
for(int j = 0;j <= b;++j)
dp[i][0][j] = 1;
for(int i = 1;i <= n;++i)
scanf("%d",&ai[i]);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
for(int k = 0;k <= b;++k){
dp[i & 1][j][k] = dp[(i - 1) & 1][j][k] % mod;
if(k - ai[i] >= 0) dp[i & 1][j][k] = (dp[i & 1][j][k] + dp[i & 1][j - 1][k - ai[i]]) % mod;
}
printf("%d\n",dp[n & 1][m][b] % mod);
}
return 0;
}
【【henuacm2016级暑期训练】动态规划专题 D】Writing Code
原文:https://www.cnblogs.com/AWCXV/p/9309411.html