1./*找零钱*/ 2021/5/18
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 5 int main() 6 { 7 int coin[5]={1,2,5,7,10}; 8 int num; 9 while(cin>>num){ 10 vector<int> dp(num+1,-1); 11 dp[0]=0; 12 for(int i=0; i<num; ++i) 13 for(int j=0; j<5; ++j) 14 if(coin[j]<=i&&dp[i-coin[j]]!=-1) 15 if(dp[i]==-1 || dp[i]>dp[i-coin[j]]+1) 16 dp[i]=dp[i-coin[j]]+1; 17 cout << dp[num-1] <<endl; 18 } 19 20 return 0; 21 }
2. 01背包
二维数组版
1 #include <iostream> 2 #include <algorithm> 3 #define Maxn 1010 4 using namespace std; 5 6 int N,V; 7 int f[Maxn][Maxn]; 8 int v[Maxn],w[Maxn]; 9 int main() 10 { 11 int result=0; 12 cin>>N>>V; 13 for(int i=1; i<=N; i++) cin >> v[i] >> w[i]; 14 for(int i=1; i<=N; i++) 15 { 16 for(int j=0; j<=V; j++) 17 { 18 if(j>=v[i]){//容量足够 19 f[i][j] = max(f[i-1][j], f[i-1][j-v[i]]+w[i]); 20 }else{ 21 f[i][j] = f[i-1][j]; 22 } 23 } 24 } 25 26 cout << f[N][V]; 27 return 0; 28 }
一维数组版
1 #include<iostream> 2 #include<algorithm> 3 #define Maxn 100000 4 using namespace std; 5 6 int f[Maxn]; 7 int v[Maxn],w[Maxn]; 8 int main() 9 { 10 11 int N,V; 12 cin >> N >> V; 13 for(int i=1; i<=N; ++i) cin>> v[i] >> w[i]; 14 for(int i=1; i<=N; i++) 15 for(int j=V; j>=v[i]; j--) 16 f[j] = max(f[j],f[j-v[i]]+w[i]); 17 cout << f[V] <<endl; 18 19 return 0; 20 }
一维01背包为什么倒序?
每次计算f[j] (即f[i][j]) 的时候都会需要f[j-w[i]] (即dp[i-1][j-w[i]])的值。因为j-w[i]比j小,所以如果我们正序计算,那么dp[j-w[i]]就已经更新了 (即dp[i][j-w[i]]),与状态转移方程不符。
3. 完全背包
二维数组版
1 #include <iostream> 2 #include <algorithm> 3 #define Maxn 1010 4 using namespace std; 5 6 int N,V; 7 int f[Maxn][Maxn]; 8 int v[Maxn],w[Maxn]; 9 int main() 10 { 11 int result=0; 12 cin>>N>>V; 13 for(int i=1; i<=N; i++) cin >> v[i] >> w[i]; 14 for(int i=0; i<=N; i++) 15 { 16 for(int j=0; j<=V; j++) 17 { 18 for(int k=0; k*v[i]<=j;k++){ 19 f[i][j] = max(f[i][j], f[i-1][j-k*v[i]]+k*w[i]); 20 } 21 } 22 } 23 cout << f[N][V]; 24 return 0; 25 }
一维数组版 loading.....