如果你是和我一样的菜鸟,不知道什么是动态规划,做这类题型建议提前仔细学习动态规划,其中典型的就是背包问题
1087:寻找最大得分的跳法
思路:分别以第1到n个点作为结束的点分析情况,其中第 i 个点的情况建立在第 i-1 个点的基础之上,以此类推,找边界情况
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n;
while(cin>>n){
if(n==0)break;
int *a=new int [n+5];
int *p=new int [n+5];
for(int i=0;i<n;i++)
cin>>a[i];
p[0]=a[0];
for(int i=1;i<n;i++)
{
p[i]=a[i];
for(int j=0;j<i;j++)
if(a[j]<a[i])
p[i]=max(p[i],p[j]+a[i]);
}
cout<<*max_element(p,p+n)<<endl;
delete a;delete p;
}
return 0;
}
1203: I need offer
(代码中有部分解释,如仍未理解可前往https://blog.csdn.net/weixin_54344261/article/details/118992488阅读详细的分析解读)
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
#define min(a,b) a<b?a:b
struct school{
int ai;
double bi;
};
int main(){
int n,m;
while(cin>>n>>m){
if(n==0&&m==0)break;
school *a=new school [m];//m个学校,每个学校有两个性质,申请费和通过率
double *p=new double [n+1];//用于存储各个剩余费用的失败率
for(int i=0;i<=n;i++)开始还没有选,则1到n之间每个费用的申请失败率初始化为1
p[i]=1.0;
int ai;
double bi;
for(int i=0;i<m;i++){
cin>>ai>>bi;
a[i].ai=ai;
a[i].bi=1.0-bi;//将输入的通过率改为失败率,后续求每个剩余费用的最小失败率即可
}
//重点!!!(口述不太好描述,可以自行一步步取值算结果,找规律)
for(int i=0;i<m;i++)
for(int j=n;j>=a[i].ai;j--)
// j>=a[j].ai 的作用相当于把 选和不选 进行了分区。每一次的选择相当于在前一个的基础上再进行分区,费用1到n之间也就有了多个区域,每个区域所代表的选与不选的意义也就不一样,也就是不同的选择方法。
p[j]=min(p[j],p[j-a[i].ai]*a[i].bi);
p[n]=1.0-p[n];//因为p[n]存的是最小失败率
p[n]=p[n]*100;
cout<<fixed<<setprecision(1)<<p[n]<<"%"<<endl;
}
}
1003:这里需要将输入的数据与处理同时进行,也就是输入一个数据就处理一次,否则存数组容易造成超时。
#include<iostream>
using namespace std;
int main(){
int n,m;
cin>>n;
int t=1;
while(t<=n){cin>>m;
int a;
int sum=0,begin=0,end=0;
int tempbegin=1;//临时子序列首元素
int max_sum=-1001; //这里最大和的赋初值为-1001 的作用就是能够确保将输入的第一个任何大小的数(在[-1000,1000]之间的数)都能够执行下叙的第一个if语句。
for(int i=1;i<=m;i++){
cin>>a;
sum+=a;
if(sum>max_sum){
max_sum=sum;
end=i;
begin=tempbegin;
}
if(sum<0){
tempbegin=i+1;
sum=0;
}
}
cout<<"Case "<<t<<":"<<endl<<max_sum<<" "<<begin<<" "<<end<<endl;
if(t<n)cout<<endl;
t++;
}
return 0;
}