【【henuacm2016級暑期訓練】動態規劃專題 D】Writing Code
阿新 • • 發佈:2018-07-14
set 方案 pen col txt clu 二維 stream bit
【鏈接】 我是鏈接,點我呀:)
【題意】
在這裏輸入題意
【題解】
二維費用背包。
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