【无标题】

作业2.1考虑下面的应用场景: 山东建筑大学烟台校区启用,现需要为n位同学分配宿舍,假设学校充分尊重同学们的意见,即可以任何x个同学使用一间宿舍(x>0),问:一共有多少种宿舍分配方案?

#include <iostream>

using namespace std;

long f(int n,int m)

{

    if(m==1||m==n)

    {

        return 1;

    }

    else{

        return f(n-1,m-1)+m*f(n-1,m);

    }

}

int main()

{

    int n,m;

    long long sum=0;

    cin>>n;

    for(int m=1 ; m<=n; m++){

        long count=f(n,m);

        sum=sum+count;

    }

    cout<<sum<<endl;

    return 0;

}

作业2.2:考虑下面的应用场景: 山东建筑大学烟台校区启用,现需要为n位同学分配至m间宿舍,问:一共有多少种宿舍分配方案?

#include <iostream>

using namespace std;

int f(int n,int m)

{

    if(m==1||m==n)

 {

        return 1;

    }

    else{

        return f(n-1,m-1)+m*f(n-1,m);

    }

}

int main()

{

    int n,m;

    cin>>n>>m;

    cout<<f(n,m)<<endl;

    return 0;

}

作业3.1现有一个二维的金字塔,由若干方格组成,每个方格里的数字表明该方格的宝物价值。 你可以选择一条从塔顶到塔底的路线(每层只能走一个方格,该方格必须为上一层走过方格的相邻方格),并收集路线上所有方格的宝物,如何选择路线,使得最终收集到的宝物价值的和最大? '
   2

  1 2

 1 2 1

#include <iostream>

#include <vector>

using namespace std;

int main(){

    int n;

    cin >> n;

   

    vector<vector<int> >p(n,vector<int>(n,0));

   

    for(int i=0;i<n;++i){

        for(int j=0;j<=i;++j){

            cin >> p[i][j];

        }

    }

    for(int i=n-2;i>=0;--i){

        for(int j=0;j<=i;++j){

            p[i][j]+=max(p[i+1][j],p[i+1][j+1]);

        }

   

 

 int max=p[0][0];

    cout << max <<endl;

   

    return 0;

}

 

作业3.2:给定一串十进制数字,共n位,要求将这些数字分成m段,由此得到了m个整数。如何划分使得m个整数的乘积最大?

数据输入:

第 1 行中包含n和m。 第2行是n位十进制整数。(n<=10)

数据输出:

输出最大乘积。

#include<iostream>  

using namespace std;  

#define N 50  

int a[N][N];  

char re[N];  

 

int f(char arr[],int i,int j)  

{  

    int sum=0;  

    while(i<=j)  

    {  

        sum = sum*10+arr[i]-'0';  

        i++;        

    }          

    return sum;  

}  

 

int main()  

{  

    int n,k,i,j,l,max,flag;  

    while(cin>>n>>k)  

    {  

        for(i=1;i<=n;i++)  

            cin>>re[i];  

        a[1][1]=re[1]-'0';  

        for(i=2;i<=n;i++)  

            a[i][1]=a[i-1][1]*10+(re[i]-'0');

        for(j=2;j<=k;j++)

        {  

            max=-1;  

            for(i=1;i<=n;i++)  

            {  

                if(j>i)  

                    a[i][j]=0;  

                else  

                {  

                    for(l=j-1;l<=i-1;l++)  

                    {  

                        flag=a[l][j-1]*f(re,l+1,i);  

                        if(flag>max)  

                        max=flag;  

                    }  

                    a[i][j]=max;  

                }  

            }  

        }  

        cout<<a[n][k]<<endl;  

    }  

    return 0;  

}

 

作业4.1:任务描述

在一条直线上,有n个宝藏,每个宝藏的坐标是ai。其中ai为整数,n <= 10000

传说曹操手下有一批摸金校尉,每个摸金校尉可以收集长度为k的一段距离内的宝藏。比如,如果一个摸金校尉从坐标为x的位置开始收集,他可以收集[x,x+n]范围内的所有宝藏。

现给出n个宝藏的坐标,问至少需要多少摸金校尉才可以收集到所有的宝藏?

输入

第一行为n和k的值,n <= 10000。 接下来一行是n个整数,代表n个宝藏的坐标ai。

输出

输出所需要的最少的摸金校尉的个数。

#include <bits/stdc++.h>

using namespace std;

int main()

{

    long n, k;

    cin >> n >> k;

    long a[n];

    for(int i = 0; i < n; ++i)

    {

        cin >> a[i];

    }

    sort(a,a+n);

    long ans = 1;

    long cur = a[0] + k;

    for(int i = 1; i < n; ++i)

    {

        if(a[i] > cur)

        {

            ++ans;

            cur = a[i] + k;

        }

    }

    cout << ans << endl;

    return 0;

}

作业4.2任务描述

设有 n 个顾客同时等待一项服务。顾客i 需要的服务时间为ti ,1 ≤ i ≤ n 。共有 s 处可以提供此项服务。应如何安排 n 个顾客的服务次序才能使平均等待时间达到最小?平均等待时间是 n 个顾客等待服务时间的总和除以 n。

编程任务:

对于给定的 n 个顾客需要的服务时间和 s 的值,编程计算最优服务次序。

数据输入:

输入数据第一行有 2 个正整数 n 和 s,表示有 n 个顾客且有 s 处可以提供顾客需要的服务。接下来的 1 行中,有 n 个正整数,表示 n 个顾客需要的服务时间。 1 ≤ n ≤ 10000

结果输出:

将计算出的最小平均等待时间输出。

#include <bits/stdc++.h>

using namespace std;

int main()

{

    long n, s;

    cin >> n >> s;

    long a[n];

    for(long i = 0; i < n; ++i)

    {

        cin >> a[i];

    }

    sort(a, a+n);

    long sum = 0;

    long t[s] = {0};

    for(long i = 0; i < n; ++i)

    {

        t[i%s] = t[i%s] + a[i];

        sum += t[i%s];

    }

    sort(t, t+s);

    double total;

    total = sum * 1.0 / n;

    cout << total << endl;

    return 0;

}

实验2.1:假设从济南到西藏的路线上共有n个城市1,2,…,n,每个城市都有一个租车公司。你可以在这些城市出租汽车,并在之后的任何一个城市归还汽车。城市i到城市j之间的租金为x(i,j),1≤i<j≤n。试设计一个算法,计算从济南(城市1)到西藏(城市n)所需的最少租金。

#include <iostream>

#include <vector>

#include <climits>

using namespace std;

int main(){

    int n;

    cin>>n;

    vector<vector<int>>f(n+1,vector<int>(n+1,0));

    vector<int>c(n+1,INT_MAX);

    for(int i=1;i<=n;i++){

        for(int j=i+1;j<=n;j++){

            cin>>f[i][j];

        }

    }

    c[1]=0;

    for(int i=2;i<=n;i++){

        c[i]=INT_MAX;

        for(int j=1;j<i;j++){

            c[i]=min(c[i],c[j]+f[j][i]);

        }

    }

    cout<<c[n]<<endl;

    return 0;

}

实验2.2:云天明送给程心一串珍贵的项链,上面共有n颗珍珠,每一颗珍珠上都有一个数字。

每两颗相邻的珍珠可以合并为一颗新的珍珠,合并后这两颗珍珠消失,新珍珠上的数字为合并的两颗的的数字之和。并且此次操作的得分要加上这个和。

经过n-1次这样的合并后,项链只剩下最后一颗珍珠,问总得分的最小值和最大值。

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

using namespace std;

const int MAXN = 205;

int pearl[MAXN], sum[MAXN];

int minpearl[MAXN][MAXN], maxpearl[MAXN][MAXN];

int main() {

    int n;

    cin >> n;

    for (int i = 1; i <= n; i++) {

        cin >> pearl[i];

        pearl[i + n] = pearl[i];

    }

   

    for (int i = 1; i <= 2 * n; i++) {

        sum[i] = sum[i - 1] + pearl[i];

}

    for (int len = 2; len <= n; len++) {

        for (int i = 1; i <= 2 * n - len + 1; i++) {

            int j = i + len - 1;

            minpearl[i][j] = INF;

            maxpearl[i][j] = 0;

            for (int k = i; k < j; k++) {

                minpearl[i][j] = min(minpearl[i][j], minpearl[i][k] + minpearl[k + 1][j] + sum[j] - sum[i - 1]);

                maxpearl[i][j] = max(maxpearl[i][j], maxpearl[i][k] + maxpearl[k + 1][j] + sum[j] - sum[i - 1]);

            }

        }

}

    int Max = 0, Min = INF;

    for (int i = 1; i <= n; i++) {

        int j = i + n - 1;

        Max = max(Max, maxpearl[i][j]);

        Min = min(Min, minpearl[i][j]);

    }

    cout << Min << endl << Max << endl;

}

实验2.3:对于长度相同的 2 个字符串 A 和 B,其距离定义为相应位置字符距离之和。2 个非空格字符的距离是它们的 ASCII 码之差的绝对值。空格与空格的距离为 0;空格与其它字符的距离为一定值 k。 在一般情况下,字符串 A 和 B 的长度不一定相同。字符串 A 的扩展是在 A 中插入若干空格字符所产生的字符串。在字符串 A 和 B 的所有长度相同的扩展中,有一对距离最小的扩展,该距离称为字符串 A 和 B 的扩展距离。 对于给定的字符串 A 和 B,试设计一个算法,计算其扩展距离。

#include <bits/stdc++.h>

using namespace std;

int dist(char c1, char c2, int k) {

    return (c1 == ' ' || c2 == ' ') ? k : abs(c1 - c2);

}

int main() {

    string a, b;

    cin >> a >> b;

    int t;

    cin >> t;

    int len1 = a.size();

    int len2 = b.size();

    vector<vector<int> > c(len1 + 1, vector<int>(len2 + 1, 0));

    for (int i = 1; i <= len1; i++) {

        c[i][0] = t * i;

    }

    for (int i = 1; i <= len2; i++) {

        c[0][i] = t * i;

    }

    for (int i = 1; i <= len1; i++) {

        for (int j = 1; j <= len2; j++) {

            c[i][j] = min(c[i - 1][j - 1] + dist(a[i - 1], b[j - 1], t),

                           min(c[i - 1][j] + t, c[i][j - 1] + t));

        }

    }

    cout << c[len1][len2] << endl;

    return 0;

}

实验2.4:现有一对双胞胎,在一个有n * n个方格的方形宝藏区域F中探宝。(i,j)方格中宝物的价值为v(i,j),如下图所示。

双胞胎均从F的A点出发,向下或向右行走,直到B点,在走过的路上,收集方格中的宝藏。试找出兄弟二人可以获得的宝藏总价的值最大。

#include <iostream>

using namespace std;

const int MAX_N = 101;

int a[MAX_N][MAX_N];

int m[MAX_N][MAX_N][MAX_N][MAX_N];

int n;

int max(int a, int b) {

    return (a > b) ? a : b;

}

void f(int x1, int y1, int x2, int y2, int t) {

    if (x1 == x2 && y1 == y2) {

        m[x1][y1][x2][y2] = max(m[x1][y1][x2][y2], t + a[x1][y1]);

    } else {

        m[x1][y1][x2][y2] = max(m[x1][y1][x2][y2], t + a[x1][y1] + a[x2][y2]);

    }

}

void GetList() {

    int x1, y1, x2, y2;

    m[1][1][1][1] = a[1][1];

    int s;

    for (s = 2; s <= 2 * n - 1; s++) {

        for (x1 = 1; x1 <= s - 1; x1++) {

            for (x2 = 1; x2 <= s - 1; x2++) {

                y1 = s - x1;

                y2 = s - x2;

                int t = m[x1][y1][x2][y2];

                f(x1 + 1, y1, x2 + 1, y2, t);

                f(x1 + 1, y1, x2, y2 + 1, t);

                f(x1, y1 + 1, x2 + 1, y2, t);

                f(x1, y1 + 1, x2, y2 + 1, t);

            }

        }

    }

}

int main() {

    cin >> n;

    int x, y, v;

    while (cin >> x >> y >> v && (x || y || v)) {

        a[x][y] = v;

    }

    GetList();

    cout << m[n][n][n][n] << endl;

    return 0;

}

实验2.5:有兄弟二人做n道题目。

已知哥哥做题目i需要时间ai,弟弟做题目i需要时间bi 。

由于兄弟二人对知识掌握的程度不同,很可能对于某些 i,有 ai ≥ bi ,而对于某些 j,j≠i,有 aj < bj 。

每一道题目只能交给二人中的一个来做。

设计一个算法,使得二人解掉所有题目所用的时间最短(从任何一人开始做题到最后一人解掉最后一道题目的总时间)。

研究一个实例: (a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。

#include <iostream>

using namespace std;

const int MAX_N = 1000;

const int MAX_TIME = 10000;

int n;

int aT = 0;

int mintime = MAX_TIME;

int a[MAX_N];

int b[MAX_N];

int c[MAX_N][MAX_TIME];

int T() {

    for (int i = 0; i <= n; i++) {

        for (int j = 0; j <= aT; j++) {

            c[i][j] = MAX_TIME;

        }

    }

    c[0][0] = 0;

    for (int i = 1; i <= n; i++) {

        for (int j = 0; j <= aT; j++) {

            c[i][j] = c[i - 1][j] + b[i];

            if (j >= a[i]) {

                c[i][j] = min(c[i][j], c[i - 1][j - a[i]]);

            }

        }

    }

    for (int j = 0; j <= aT; j++) {

        int t = max(c[n][j], j);

        mintime = min(mintime, t);

    }

    return mintime;

}

 

int main() {

    cin >> n;

    for (int i = 1; i <= n; i++) {

        cin >> a[i];

        aT += a[i];

    }

    for (int i = 1; i <= n; i++) {

        cin >> b[i];

    }

    T();

    cout << mintime << endl;

    return 0;

}

实验2.6作为一个比赛队伍总教练的你,请解决下面的问题:

你作为总教练的聘期为n天。

在这n天里,一共有n个比赛可以参加。

队员们都愿意参加比赛,而不愿意训练,所以希望有比赛就参加。

如果在某一天有多场比赛同时开始,作为主教练的你可任选其中一场比赛参加(前提是队伍没有正在参加的比赛)。

比赛从第s天开始,持续t天,则该比赛在第 s+t-1 天结束。

作为总教练的你,应该如何选择比赛,才能既使得队员满意

#include <bits/stdc++.h>

using namespace std;

vector<int> a, b, c;

int main() {

    int n, x;

    cin >> n >> x;

    a.resize(n + 2, INT_MAX);

    b.resize(x + 1);

    c.resize(x + 1);

    for (int i = 1; i <= x; i++) {

        int y, t;

        cin >> y >> t;

        b[i] = y;

        c[i] = t;

    }

    int m = 0;

    for (int i = n; i >= 1; i--) {

        a[n + 1] = n;

        for (int j = 1; j <= x; j++) {

            if (b[j] == i) {

                a[i] = min(a[b[j] + c[j]], a[i]);

                m += 1;

            }

        }

        if (m == 0) {

            a[i] = a[i + 1] - 1;

        }

        m = 0;

    }

    cout << a[1];

    return 0;

}

实验3.1问题描述:

山东建筑大学有足够多的教室,可以安排一学期内的所有课程。当然,教务处希望使用的教室数量越少越好。设计一个有效的贪心算法进行排课。

编程任务:

对于给出的 n 个待排课的课程,编程计算使用最少教室的数量。0 ≤ n ≤ 10000。

数据输入:

输入数据第一行有 1 个正整数 n,表示有 n 个待排课的课程。 接下来的 n 行中,每行有 2 个正整数,分别表示 n 个待排课程的开始时间和结束时间。时间以 0 点开始的分钟计。

结果输出:

输出需要的最少教室数量。

#include <iostream>

#include <algorithm>

using namespace std;

int Minclassroom(pair<int, int>* courses, int n) {

    sort(courses, courses + n);// 按开始时间排序

    int* endtime = new int[n];// 动态数组来记录每个教室的结束时间

    endtime[0] = courses[0].second;// 将第一个课程的结束时间存入endtime数组中

    int endtimeCount = 1;// 记录教室数量的变量

    for (int i = 1; i < n; i++) {

        bool hasRoom = false;

        for (int j = 0; j < endtimeCount; j++) {

            if (courses[i].first >= endtime[j]) {

                endtime[j] = courses[i].second;// 将课程安排到已有教室中

                hasRoom = true;

                break;

            }

        }

        if (!hasRoom) {

            endtime[endtimeCount] = courses[i].second;// 需要额外开设一个教室,并将时间加入到endtime数组中

            endtimeCount++;

        }

    }

    delete[] endtime;// 释放动态数组的内存空间

    return endtimeCount;// 返回最少教室数量

}

int main() {

    int n;

    cin >> n;

    pair<int, int>* courses = new pair<int, int>[n];// 动态数组来存储课程的开始和结束时间

    for (int i = 0; i < n; i++) {

        cin >> courses[i].first >> courses[i].second;// 读取课程的开始时间和结束时间

    }

    int minClassrooms = Minclassroom(courses, n);// 计算最少教室数量

    cout << minClassrooms << endl;// 输出最少教室数量

    delete[] courses;// 释放动态数组的内存空间

    return 0;

}

实验3.2:设有 n 个程序{1,2,…, n }要存放在长度为 L 的磁带上。程序 i 存放在磁带上的长度是li ,1 ≤ i ≤ n 。这 n 个程序的读取概率分别是p1, p2 ,……, pn ,且 ∑pi(i=1~n) = 1。

如果将这 n 个程序按i1,i2 ,……,in 的次序存放,则读取程序ir 所需的时间tr = c*∑pi li (i=1 ~ r)。这 n 个程序的平均读取时间为∑tr (r=1 ~ n)。

磁带最优存储问题要求确定这 n 个程序在磁带上的一个存储次序,使平均读取时间达到最小。试设计一个解此问题的算法,并分析算法的正确性和计算复杂性。

#include<iostream>

#include<queue>

using namespace std;

struct Tape

{

    int len;

    int pr;

    double tr;

    friend bool operator< (Tape a,Tape b) { return a.tr > b.tr; }

    Tape(int l=0,int p=0):len(l),pr(p),tr(l*p) {}

};

double minTimeCost(priority_queue<Tape>& tape, long long sum)

{

    double res = 0, acc = 0;

    while (!tape.empty())

    {

        acc += tape.top().tr / sum;

        res += acc;

        tape.pop();

    }

    return res;

}

int main()

{

    int n, a, b;

    long long sum = 0;

    cout << "";

    cin >> n;

    priority_queue<Tape> tape;

    cout << "" << endl;

    for (int i = 0; i < n; i++)

    {

        cin >> a >> b;

        tape.push(Tape(a,b));

        sum += b;

    }

    double res = minTimeCost(tape, sum);

    cout << "" << res << endl;

    return 0;

}

实验4.1问题描述:

95枪族是我国现役主力步枪之一。假设某95步枪由 n 个部件组成,每一种部件都可以从 m 个不同的供应商处购得。设 wij 是从供应商 j 处购得的部件 i 的重量,cij 是相应的价格。 试设计一个算法,给出总价格不超过 c 的最小重量步枪的部分采购方案。

编程任务:

对于给定的步枪部件重量和步枪部件价格,编程计算总价格不超过 d 的最小重量步枪设计。

数据输入:

输入数据第一行有 3 个正整数 n ,m 和 d。接下来的 2n 行,每行 m 个数。前 n 行是 c,后 n 行是 w。 1 <= n, m <= 20。

结果输出:

将计算出的最小重量输入,并输出每个部件的供应商。

#include <iostream>

using namespace std;

int n,m;

int d,cw=0,cp=0,minp=0,minw=0;

int bestw=9999999,x[27],bestx[27],w[27][27],c[27][27],rp[27],rw[27];

bool backtrack(int i){

    if(i>n){

        bestw=cw;

        for(int j=1;j<=n;j++){

            bestx[j]=x[j];

        }

        return true;

    }

    bool found=false;

    for(int j=1;j <= m;j++){

        x[i]=j;

        cw+=w[i][j];

        cp+=c[i][j];

        minp-=rp[i];

        minw-=rw[i];

        if(cw+minw < bestw && cp+minp <= d){

            if(backtrack(i+1)){

                found=true;

            }

        }

        cp-=c[i][j];

        cw-=w[i][j];

        minp+=rp[i];

        minw+=rw[i];

    }

    return found;

}

int main(){

    cin>>n>>m>>d;

    int temp=999999;

    for(int i=1;i<=n;i++){

        for(int j=1;j<=m;j++){

            cin>>c[i][j];

            if(c[i][j] < temp) temp=c[i][j];

        }

        rp[i]=temp;

        minp+=rp[i];

        temp=999999;

    }

    for(int i=1;i<=n;i++){

        for(int j=1;j<=m;j++){

            cin>>w[i][j];

            if(w[i][j] < temp) temp=w[i][j];

        }

        rw[i]=temp;

        minw+=rw[i];

        temp=999999;

    }

    backtrack(1);

    cout<<bestw<<endl;

    for(int i=1;i<=n;i++){

        cout<<bestx[i]<<" ";

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值