ACM-ICPC基本算法思想

正在更新中

  • 求值法

  • 遞推法

  • 遞歸法

  • 枚舉法

  • 模擬法

    將自然的過程或者語言直白的程序化,比如題目中的求解過程,我們直接程序化模擬求解。即根據實際問題建立模型,模擬實際玩法從而解決問題。
    (1)隨機模擬

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	int i,s;
	long t;
	cin>>n;
	t=time(NULL)%1000;   //rand()%(b-a+1)+a;    rand()%(80-20+1)+20 
	srand(t);
	for(t=0,i=1;i<=n;i++)
	t=t+rand()%61+20;
	s=t/10;
	cout<<s;
	return 0;
}

(2)過程模擬

在這裏插入圖片描述
問題分析:輸入第一行n代表有幾組數,輸入第二行m代表電梯要停幾層,隨後跟着輸入m個數代表要電梯停的樓層

每上一層樓電梯要用6分鐘,每下一層樓電梯要用4分鐘,在樓層中停要用5分鐘


#include<bits/stdc++.h>
using namespace std;
int main(){
	int N;
	while(cin>>N,N!=0){
		int t=0;
		int sum=0;
		while(N--){
			int s;
			cin>>s;
			if(s-t>0)
			sum=sum+(s-t)*6+5;
			else
			sum=sum+(t-s)*4+5;
			t=s;
		}
		cout<<sum<<endl;
	}
	return 0;
}
  • 分治法

    在計算機科學中,分治法是一種很重要的算法。字面上的解釋是“分而治之”,就是把一個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。這個技巧是很多高效算法的基礎,如排序算法(快速排序,歸併排序),傅立葉變換(快速傅立葉變換)……
      任何一個可以用計算機求解的問題所需的計算時間都與其規模有關。問題的規模越小,越容易直接求解,解題所需的計算時間也越少。例如,對於n個元素的排序問題,當n=1時,不需任何計算。n=2時,只要作一次比較即可排好序。n=3時只要作3次比較即可,…。而當n較大時,問題就不那麼容易處理了。要想直接解決一個規模較大的問題,有時是相當困難的。這時候,分治法就起很大的作用了。
    在這裏插入圖片描述
#include<bits/stdc++.h>
using namespace std;
int w[1000001];
void gold(int low,int high,int *max,int *min){
	int x1,x2,y1,y2;
	int mid;
	if(low==high)
	*max=*min=w[low];
	else if((high-low)==1){
		if(w[high]>w[low]){
			*max=w[high];
			*min=w[low];
		} 
		else{
			*max=w[low];
			*min=w[high];
		}
	} 
	else{
		mid=(low+high)/2;
		gold(low,mid,&x1,&y1);
		gold(mid+1,high,&x2,&y2);
		*max=(x1>x2)?x1:x2;
		*min=(y1<y2)?y1:y2;
	}
}
int main(){
	int m,i;
	int max,min;
	cin>>m;
	for(i=1;i<=m;i++){
		cin>>w[i];
	}
	gold(1,m,&max,&min);
	cout<<max<<" "<<min;
	return 0;
}
  • 貪心法

  • 回溯法

回溯法又稱爲試探法,是一種在解空間中搜索問題解的方法。

  • 構造法

構造法是通過構造數學模型或方法解決問題的。
構造法解題類型有:
(1)數學建模
(2)直接構造

  • 動態規劃法

/*數塔問題  動態規劃法*/
/*動態規劃並不是貪心,貪心是逐步獲得最優解,其分解的子問題是相互獨立得 
  而動態規劃是求解決策過程最優化,其分解的子問題並不相互獨立*/ 
#include<bits/stdc++.h>
using namespace std;
#define N 50
int a[N][N][3];
int n;
void operate(){
	int i,j;
	for(i=n-1;i>=1;i--)				//從底向上計算 
	for(j=1;j<=i;j++){
		if(a[i+1][j][2]>a[i+1][j+1][2])
		a[i][j][2]+=a[i+1][j][2];
		else{
			a[i][j][2]+=a[i+1][j+1][2];
			a[i][j][0]=1;
		} 
	}
} 
int main(){
	int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	for(j=1;j<=i;j++){
		cin>>a[i][j][1];
		a[i][j][2]=a[i][j][1];
		a[i][j][0]=0;
	}
	operate();
	cout<<a[1][1][2]<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章