20211111C++练习总结
第一题:铺放骨牌F302
链接:铺放骨牌F302
题目分析
题型:DP(动态规划)(了解动态规划看我博客)
状态定义: (1维即可) f [ i ] 表示当长方形为2*i时,摆放的方法数
状态转移方程: 我们要考虑 2 * (i - 1) 和 2 * (i - 2)摆法相加即可,也就是斐波那契数列
状态初始化:前两个状态也就是 f[1] 和 f[2] 手算出 f[1] = 1 , f[2] = 2
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+10;
int n;
int f[maxn];//f[i]表示在2*i的矩形中摆法数
int main(){
scanf("%d",&n);
//状态初始化
f[1]=1;
f[2]=2;
//状态转移方程
for(int i=3;i<=n;i++)f[i]=f[i-1]+f[i-2];
printf("%d\n",f[n]);
return 0;
}
第二题:放苹果F403
链接:放苹果F403
题目分析
题型:DP
状态定义:(3维) f[i][j][k]表示i个盘子j个苹果每个盘子的苹果不超过k个
状态转移方程:每次在 0 ~ min( j , k )把 f[i-1][j-w][w]加起来
状态初始化(分两种):1. f[0][0][i] || 0<=i<=n 注意:f[0][0][i]=1 什么都没有也算!
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=10+10;
int t,n,m;
int f[maxn][maxn][maxn];//状态定义:f[i][j][k]表示i个盘子j个苹果每个盘子的苹果不超过k个
int main(){
cin>>t;
//多组数据
while(t--){
memset(f,0,sizeof(f));
cin>>n>>m;
//状态初始化
for(int i=0;i<=n;i++)f[0][0][i]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=n;j++)f[0][i][j]=0;
}
//状态转移方程
for(int i=1;i<=m;i++){
for(int j=0;j<=n;j++){
for(int k=0;k<=n;k++){
f[i][j][k]=0;
for(int w=0;w<=min(j,k);w++)f[i][j][k]+=f[i-1][j-w][w];
}
}
}
cout<<f[m][n][n]<<endl;
}
return 0;
}
第三题:排队打水F601
链接:排队打水F601
题目分析
题型: 贪心
思路: 肯定是接水时间少的人先接水才能使等待时间最小化
1. 先将每人接水时间按照题目所说规则从小–>大排序
2. 循环统计总等待时间
3. 输出排队顺序及平均时间(总等待时间 / 总人数)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int n;
double ans;
struct node{
int w,e;
}a[maxn];
bool cmp(node x,node y){
if(x.w!=y.w)return x.w<y.w;
return x.e<y.e;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].w);
a[i].e=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)ans=ans+a[i].w*(n-i+1);
ans=ans*1.0/n;
for(int i=1;i<=n;i++)printf("%d ",a[i].e);
printf("\n%.2lf\n",ans);
return 0;
}
第四题: 活动选择F604
链接:活动选择F604
题目分析
题型: 贪心
思路:可以将所有活动结束的时间排序进行最优求解
1.将所有活动的结束时间按照从小–>大的顺序排序
2.第一个活动必选,其次活动按下标顺序依次遍历并计数
3.输出最多安排活动数
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int n,ans;
struct node{
int b,e;
void input(){
scanf("%d%d",&b,&e);
}
}a[maxn];
bool cmp(node x,node y){
return x.e<y.e;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)a[i].input();
sort(a+1,a+n+1,cmp);
int s=a[1].e;
ans++;
for(int i=2;i<=n;i++){
if(a[i].b>=s){
ans++;
s=a[i].e;
}
}
printf("%d\n",ans);
return 0;
}
希望大家多多评论,本人尽量改进