# Contest1143 - 计算思维实训-ACM程序设计练习

#include<bits/stdc++.h>
using namespace std;
long long dp[10000];
void dpp(int n){
dp[0] = 0;
dp[1] = 1;
for(int i = 2;i<=47;i++){
dp[i] = dp[i-1]+dp[i-2];
}
}
int main(){
int n;
dpp(47);
while(cin>>n&&n!=-1){
int yn  =0;
for(int i = 0;i<=47;i++){
if(dp[i] == n){
cout<<i<<endl;
yn = 1;
break;
}
}
if(yn == 0)cout<<"Not a Fibonacci number."<<endl;
}
}


B: 点击打开链接

#include<bits/stdc++.h>
using namespace std;
long long dp[66];
void dpp (){
dp[1] =  3;
dp[2] = 6;
dp[3] = 6;
for(int i = 4;i<62;i++){
dp[i] = dp[i-1]+2*dp[i-2];
}
}
int main(){
int n;
dpp();
while(cin>>n){
cout<<dp[n]<<endl;
}
}



D:

http://202.121.199.212/JudgeOnline/problem.php?cid=1143&pid=3

c数组输出可以得到过河过程

#include<bits/stdc++.h>
using namespace std;
int a[1005];
int b[5];
int c[1000][2];
int main(){
int n;
while(cin>>n){
for(int i = 0;i<n;i++)cin>>a[i];
sort(a,a+n);
if(n == 1){cout<<a[0]<<endl;continue;}
//if(n == 2){cout<<a[1]<<endl;continue;}
int t = n;
b[0] = a[0];
b[1] = a[1];
int m = 1;
long long sum = 0;
int cnt = 0;
while(t>0){
if(n>2&&t>2){
if(m == 1){

//  cout<<b[1]<<" "<<b[0]<<endl;
//  cout<<b[0]<<endl;
c[++cnt][0]= b[0];
c[cnt][1] = b[1];
c[++cnt][0] = b[0];
sum += b[1]+b[0];
t=t-1;
m = 0;
}
else{

c[++cnt][0]= a[n-2];
c[cnt][1] = a[n-1];
c[++cnt][0] = b[1];
//  cout<<a[n-2]<<" "<<a[n-1]<<endl;
//  cout<<b[1]<<endl;
sum+= a[n-1]+b[1];
n-=2;
t-=1;
m++;
}
}
else{
if(m == 1){
//  cout<<b[1]<<" "<<b[0]<<endl;
sum += b[1];
m = 0;
t-=2;
c[++cnt][0]= b[0];
c[cnt][1] = b[1];
}
else {
sum+= a[n-1];
//  cout<<a[0]<<" "<<a[n-1]<<endl;

c[++cnt][0]= b[0];
c[cnt][1] = a[n-1];
n-=2;
t-=2;
m++;
}
}
//cout<<sum<<endl;
}
cout<<sum<<endl;
/*for(int i = 1;i<=cnt;i++){
if(c[i][1] != 0)
cout<<c[i][0]<<" "<<c[i][1]<<endl;
else  cout<<c[i][0]<<endl;
}*/
}
}
F:

  #include <iostream>
#include<cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e5 + 5;
int s[N];
int n,p,a[N];
int len;
int main()
{
//  cin>>n;
while(cin>>p){

memset(s,0,sizeof(s));
for(int i = 0;i<p;i++)cin>>a[i];
s[1] = a[0];len = 1;//长度从1开始
for(int i = 1;i<p;i++){

int t = a[i];
if(t>s[len])s[++len] = a[i];
else{
/*************/int l = 1,r = len,mid;//这里的二分法采用了左闭右闭的思路
int ans = 0;
while(l<=r)
{
mid = (l+r)/2;
if(s[mid]<t)
{l = mid +1;ans = max(ans,mid);}//ans即为思路中的j，j必然为s数组中小于t的最大的数
else r = mid-1;
}
s[ans+1] = t;/******************/
}
}
//for(int i = 1;i<p;i++){cout<<s[i];}//有必要可以打开看看s中存的是什么值
cout<<len<<endl;
}
return 0;
}