[kuangbin带你飞]专题十二 基础DP1
E题
题意:
有n个位置,每个位置有一个标号,player从起始点出发,每次只能往前跳,并且跳到的位置的标号要比上一次位置的大,途径的位置越多,分数越高,选择一种跳法,使得分最大。
解法:
<一>用set
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int all[maxn];
struct re
{
int score,big;
bool operator<(const re &a)const
{
if(score!=a.score)return score>a.score;
else return big<a.big;
}
void fu(int a,int b)
{
score=a;big=b;
}
};
re dp[maxn][2];
set<re>have;
int main(void)
{
int n;
while(scanf("%d",&n)&&n)
{
have.clear();
have.insert(re{0,0});
for(int i=1;i<=n;++i)
{
int a;
scanf("%d",&a);
re tem;
set<re>::iterator it=have.begin();
for(;it!=have.end();++it)
{
// printf("score=%d big=%d\n",it->score,it->big);
if((it->big) <a)
{
// printf("a=%d big=%d score=%d \n",a,it->big,it->score);
tem.fu((it->score)+a,a);
have.insert(tem);
break;
}
}
//printf("kkk");
}
set<re>::iterator it=have.begin();
cout<<(it->score)<<endl;
}
}
<二>直接暴力,每一步是建立在比它小的上一步的最优值之上,那就扫一遍,时间复杂度为n*n
#include<bits/stdc++.h>
using namespace std;
struct re
{
int big,val;
};
const int maxn=1e3+10;
re all[maxn];
int main(void)
{
int n;
while(scanf("%d",&n)&&n)
{
int ans=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&all[i].big);
all[i].val=all[i].big;
for(int d=1;d<i;++d)
if(all[d].big<all[i].big)all[i].val=max(all[i].val,all[d].val+all[i].big);
ans=max(ans,all[i].val);
}
printf("%d\n",ans);
}
return 0;
}