[算法設計]代碼複習筆記

考試內容

分治算法

B - 整數因子分解問題
#include<bits/stdc++.h>
using namespace std;
//用map開一個數組(大)
map<int ,int >a;
int f(int n){
    if(n == 1)
        return 1;
    if(a[n])
        return a[n];
    //curCount爲n的分解數,初始值爲1(自己是自己的因子)
    int curCount=1;
    for(int i=2;i<=sqrt(n);i++){
        if(n%i == 0){
            curCount+=f(i);
            //因爲循環到sqrt(n),如果n/i此時的值
            //不等於i,則繼續分解n/i,並將返回的結果
            //加到curCount上
            if(i!=n/i){
                curCount+=f(n/i);
            }
        }
    }
    a[n] = curCount;
    return a[n];
}
int main()
{
    int n;
    while(cin>>n){
        cout<<f(n)<<endl;
    }
}
C - 順序表應用7:最大子段和之分治遞歸法
#include<bits/stdc++.h>
using namespace std;
int n,arr[200200];//開數組存數字
int c= 0;//遞歸次數
int rec(int l,int r){
    int sum = 0;
    c++;
    //當左右相等時
    if(l==r){
        if(arr[l]>=0)
            sum = arr[l];
        else
            sum = 0;
    }
    else
    {
        int  mid = (l+r)>>1;
        int leftsum = rec(l,mid);
        int rightsum = rec(mid+1,r);

        int s1,s2,ss;

        s1 = ss =0;
        for(int i=mid;i>=l;--i){
            ss+=arr[i];
            s1 = max(ss,s1);
        }

        s2 = ss =0;
        for ( int i=mid+1;i<=r;++i){
            ss+=arr[i];
            s2 = max(ss,s2);
        }

        sum = max(max(s1+s2,leftsum),rightsum);
    }
    return sum;
}

int main(){
    scanf("%d",&n);
    for(int i = 0; i<n; ++i)
		scanf("%d", &arr[i]);
    cout<<rec(0,n-1)<<" "<<c<<endl;
    return 0;
}

參考資料

https://www.luogu.org/problemnew/solution/P1115 最大子段和

動態規劃

B - 最少硬幣問題
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int dp[20020];
int main(){
    int n;
    cin>>n;
    int coins[n];
    int T[n];
    for(int i=0;i<n;i++){
        cin>>T[i]>>coins[i];
    }
    int m;
    cin>>m;
    for(int i=1;i<=m;i++) dp[i]=INF;
    for(int i=0;i<n;i++)
        for(int j=1;j<= coins[i];i++)
            for(int k=m;k>=T[i];k--)
                dp[k]=min(dp[k],dp[k-T[i]]+1);
    cout<<(dp[m]<m?dp[m]:-1)<<endl;
}
D - 石子合併問題

暫無

E - 最長公共子序列問題
#include<bits/stdc++.h>
using namespace std;

    int findLCS(string A, string B)
    {
        int n= A.length(),m=B.length();
        if(n == 0 || m == 0)//特殊輸入
            return 0;
        int dp[n + 1][m + 1];//定義狀態數組
        for(int i = 0 ; i <= n; i++)//初始狀態
            dp[i][0] = 0;
        for(int i = 0; i <= m; i++)
            dp[0][i] = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j<= m; j++)
            {
                if(A[i - 1] == B[j - 1])//判斷A的第i個字符和B的第j個字符是否相同
                    dp[i][j] = dp[i -1][j - 1] + 1;
                else
                    dp[i][j] = max(dp[i - 1][j],dp[i][j - 1]);
            }
            return dp[n][m];//最終的返回結果就是dp[n][m]
    }

int main()
{
    int n;
    string s1,s2;
    while(cin>>s1){
        cin>>s2;
        cout<<findLCS(s1,s2)<<endl;

    }
}

貪心算法練習

A 2072] - 刪數問題
#include <bits/stdc++.h>

using namespace std;


int main()
{
    string a;
    int n,i,j,k;
    cin>>a>>n;
    int len=a.size();
    for(k=0;k<n;k++)   //這個循環控制刪數的次數
    {
        for(i=0;i<len-1;i++)    //這個循環比較此位和下一位的大小
        {
            if(a[i]>a[i+1])    //刪數
            {
                for(j=i;j<len-1;j++)
                    a[j]=a[j+1];
                break;  //刪完數後,應該跳出循環,進行下一次找數刪數(break不能跳出if);n次刪數;
            }
        }
        len--;    //如果不滿足條件 (都是遞增的數),那麼長度直接減1;適用於123456這種情況;其實不管滿		不滿足比較的條件,長度都會減1
    }

    i=0;
    while(i<=len-1&&a[i]=='0')
        i++;

    if(i==len)
        cout<<"0"<<endl;
    else
        for(j=i;j<=len-1;j++)
            cout<<a[j];
    return 0;
}
活動選擇
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
struct node{
    int _num;
    int _beg;
    int _end;
}a[101];
bool cmp(node a,node b){
    return a._end < b._end;
}

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i]._beg>>a[i]._end;
        a[i]._num = i+1;
    }
    sort(a,a+n,cmp);
    int mmax = a[0]._end;
    cout<<a[0]._num;
    for(int i=1;i<n;i++)
    {
       //cout<<a[i]._num<<" "<<a[i]._beg<<" "<<a[i]._end<<endl;
        if(a[i]._beg>=mmax){
            cout<<","<<a[i]._num;
            mmax = a[i]._end;
        }

    }

}


活動選擇問題
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
struct node{
    int _num;
    int _beg;
    int _end;
}a[101];
bool cmp(node a,node b){
    return a._end < b._end;
}

int main(){
    int n;
    while(cin>>n){
        for(int i=0;i<n;i++)
    {
        cin>>a[i]._beg>>a[i]._end;
        a[i]._num = i+1;
    }
    sort(a,a+n,cmp);
    int mmax = a[0]._end;
    //cout<<a[0]._num;
    int sum= 1;
    for(int i=1;i<n;i++)
    {
       //cout<<a[i]._num<<" "<<a[i]._beg<<" "<<a[i]._end<<endl;
        if(a[i]._beg>=mmax){
            sum++;
            mmax = a[i]._end;
        }

    }
    cout<<sum<<endl;

    }


}


D 2074] - 區間覆蓋問題
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
struct node{
    int bg;
    int ed;
}a[201];
int b[201];
bool cmp(node a,node b){
    return a.ed<b.ed;
}
bool cmp1(int  a,int b){
    return a>b;
}
int main(){
    int n;
    int m;
    while(cin>>n){
        cin>>m;
        for(int i=0; i<n;i++){
            cin>>a[i].ed;
            a[i].bg = a[i].ed-1;
        }
        sort(a,a+n,cmp);
        int s = a[n-1].ed-a[0].bg;
         for(int i=0; i<n-1;i++){
           // cout<<a[i].bg<<" "<<a[i].ed<<endl;
            b[i]= a[i+1].bg-a[i].ed;
        }
        sort(b,b+n-1,cmp1);
        if(m>=n)
            s = n;
        else
            for(int i=0;i<m-1;i++)
            s-=b[i];
        cout<<s<<endl;
    }
}

E 最少攔截系統
#include<bits/stdc++.h>
using namespace std;
int main(){
    int m,n;
    while(cin>>n){
        int a[100];
        int sum= 1;
        cin>>a[0];
        int j;
        for(int i=1;i<n;i++){
            cin>>m;
            int f=0;
            for(int j=0;j<sum;j++){
                if(a[j]>= m ){
                    a[j] = m;
                    f=1;
                    break;
                }
            }
            if(f==0)
                a[sum++]=m;
        }
        cout<<sum<<endl;
    }
}

搜索回溯框架

整數變換問題

回溯框架

#include<bits/stdc++.h>

using namespace std;

int cnt = 0,cn = 0;
char a[10010];

int fun(int i, int sum)                    //分別計算兩種函數
{
    if(i == 0)
        return sum*3;
    else
        return sum/2;
}

bool traceback(int n, int m, int dept)
{
    if(dept > cnt)                 //當前的深度不能使n變成m
        return false;
    int sum = n;
    for(int i = 0; i < 2; i++)
    {
        sum = fun(i,n);
        if(sum == m || traceback(sum,m,dept+1))
        {
            if(i == 0)
                a[cn++] = 'f';
            else
                a[cn++] = 'g';
            return true;
        }
    }
    return false;
}

int main()
{
    int  n,m;
    cnt = 1;
    cin>>n>>m;
    while(!traceback(n,m,1))
    {
        cnt++;
    }
    cout<<cnt<<endl;
    for(int i = 0;  i < cn; i++)
        cout<<a[i];
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章