- 题解
2024 暑假C++
- 2024-7-15 16:55:41 @
斐波那契和他的不死兔子🐰
方法1(数字<50):
#include <iostream>
using namespace std;
int fibo(int n){
if (n == 1 || n == 2){
return 1;
}
return fibo(n-1) + fibo(n-2);
return 0;
}
int main(){
int n;
cin >> n;
cout << "第" << n << "个月有" << fibo(n) << "只🐰";
return 0;
}
方法2(数字不限):
#include <iostream>
using namespace std;
long long memo[100];
long long fibo(int n , long long memo[]){
if (n == 1 || n == 2){
memo[n] = 1;
return 1;
}
if (memo[n] != 0){
return memo[n];
}else{
memo[n] = fibo(n-1 , memo) + fibo(n-2 , memo);
return memo[n];
}
return 0;
}
int main(){
int n;
cin >> n;
cout << "第" << n << "个月有" << fibo(n,memo) << "只🐰";
return 0;
}
练习:
【例48.1】 斐波那契数列
方法1:
#include <iostream>
using namespace std;
typedef long long ll;
ll fibo(int n){
if(n==1) return 0;
if(n==2) return 1;
return fibo(n-1)+fibo(n-2);
}
int main(){
int n;
cin >> n;
n --;
cout << fibo(n);
return 0;
}
方法2(标准):
#include <iostream>
using namespace std;
long long memo[100];
long long fibo(long long n , long long memo[]){
if(n == 1 || n == 2){
memo[n] = 1;
return 1;
}
if (memo[n] != 0){
return memo[n];
}else{
memo[n] = fibo(n - 1, memo) + fibo(n-2,memo);
return memo[n];
}
return 0;
}
int main(){
long long n;
cin >> n;
n = n - 1;
cout << fibo(n,memo) << endl;
return 0;
}
方法3(标准+严谨):
#include <iostream>
using namespace std;
typedef long long ll;
long long memo[100] = {0,0,1,1,2};
ll fibo(int n , ll memo[]){
if (memo[n] == 0){
memo[n] = fibo(n-1,memo) + fibo(n-2,memo);
}
if (n == 2 or n == 1){
return memo[n];
}
return memo[n];
}
int main(){
int n;
cin >> n;
cout << fibo(n,memo);
return 0;
}
「一本通 6.5 练习 1」Fibonacci
#include <iostream>
using namespace std;
int memo[100];
int fibo(int n , int memo[]){
if (n == 1){
memo[n] = 1;
return memo[n];
}
if (n == 0){
memo[n] = 0;
return memo[n];
}
if (memo[n] != 0){
return memo[n];
}
memo[n] = fibo(n-1,memo) + fibo(n-2,memo);
return memo[n];
}
int main(){
int n = 5;
cout << fibo(n,memo);
return 0;
}
银币找零💰
方法一:
#include <iostream>
using namespace std;
int mec(int change){
if (change==0) return 0;
if (change<0) return -1;
int count = 10000;
if (change >= 5){
count = min(count,mec(change-5)+1);
}
if (change >= 2){
count = min(count,mec(change-2)+1);
}
if (change >= 1){
count = min(count,mec(change-1)+1);
}
return count;
}
int main(){
int n ;
cin >> n;
cout << mec(n);
}
练习:面额是1、2、5,用记忆化递归
方法一(递归)
#include <iostream>
using namespace std;
int memo[10000];
long long cnt = 10000000;
int mec(int change,int memo[]){
if (change==0) return 0;
if (change<0) return -1;
int count = 10000;
if(memo[change] == 0){
if (change >= 5){
count = min(count,mec(change-5,memo)+1);
memo[change] = count;
}
if (change >= 2){
count = min(count,mec(change-2,memo)+1);
memo[change] = count;
}
if (change >= 1){
count = min(count,mec(change-1,memo)+1);
memo[change] = count;
}
memo[change];
}
return memo[change];
}
int main(){
int n ;
cin >> n;
cout << mec(n,memo);
}
练习
【动态规划法】硬币找零问题
方法一(递归)
#include <cstdio>
#include <iostream>
using namespace std;
int coins[10];
int num = 0;
int memo[20];
int mec(int change , int memo[]){
if(change == 0) return 0;
if(change < 0) return -1;
int minN = 1000;
if(memo[change] != 0) return memo[change];
for (int i = 0 ; i < num ; i ++){
if(change >= coins[i]){
int tmp = 1 + mec(change - coins[i],memo);
minN = min(minN,tmp);
}
memo[change] = minN;
}
return memo[change];
}
int main(){
int change;
cin >> change;
while (1){
cin >> coins[num ++];
if(getchar()== '\n') break;
}
cout << mec(change,memo);
return 0;
}
方法二(递推)
#include <cstdio>
#include <iostream>
using namespace std;
int coins[10];
int num = 0;
const int MN = 100;
int memo[MN];
void mec(int change,int memo[]){
memo[0] = 0;
for (int i = 1 ; i < change ; i++){
memo[i] = -1;
}
for (int k = 1 ; k< change;k++){
for (int j = 0 ; j < num ; j++){
if (k >= coins[j]){
int tmp = 1+ memo[k - coins[j]];
if (memo[k] == -1){
memo[k] = tmp;
}
if (tmp < memo[k]){
memo[k] = tmp;
}
}
}
}
}
int main(){
int change;
cin >> change;
int n = 10;
while (n--){
cin >> coins[num ++];
if(getchar()== '\n') break;
}
mec(MN,memo);
cout << memo[change];
return 0;
}
坐标格子⬛️
无限制条件
#include <iostream>
using namespace std;
const int N = 55;
int dp[N][N];
void go(){
for (int i = 1 ; i <= N ; i++){
if(i == 1|| j == 1){
dp[i][j] = 1;
}else{
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
}
}
int main(){
int n , m;
cin >> n >> m;
go();
cout << dp[n][m];
return 0;
}
有限制条件
#include <iostream>
using namespace std;
const int N = 55;
int dp[N][N];
void go(){
for (int i = 1 ; i <= N ; i++){
for (int j = 1 ; j <= N ;j++){
if (i%2==0 && j%2==0){
dp[i][j] = 0;
continue;
}
if(i == 1|| j == 1){
dp[i][j] = 1;
}else{
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
}
}
int main(){
int n , m;
cin >> n >> m;
go();
cout << dp[n][m];
return 0;
}
背包问题🎒
#include <iostream>
using namespace std;
int v[4] = {0,1500,3000,2000};
int w[4] = {0,1,4,3};
const int N = 20;
int dp[N][N] = {0};
void go(){
for (int i = 1 ; i <= 3 ; i ++){
for (int j = 1 ; j <= 4 ; j ++){
if(j >= w[i]){
int tmp = v[i] + dp[i-1][j-w[i]];
dp[i][j] = max(tmp,dp[i-1][j]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
}
int main(){
go();
int n , m;
cin >> n >> m;
cout << dp[n][m];
return 0;
}
练习:
【例9.11】01背包问题
#include <bits/stdc++.h>
using namespace std;
int w[35] = {0};
int c[35] = {0};
int d1[205] = {0};
int main(){
int m,n;
cin >> m >> n;
for(int i = 1 ; i <= n;i++){
cin >> w[i] >> c[i];
}
for(int i = 1 ; i<=n; i++){
for(int k = m ; k >= w[i] ; --k){
d1[k] = max(d1[k], c[i] + d1[k-w[i]] );
}
}
cout << d1[m] << endl;
return 0;
}
【例9.12】完全背包问题
0 条评论
目前还没有评论...