当前位置: 首页 > news >正文

算法设计作业

第四章(贪心算法)

4.1最短路径-Dijkstra

输入格式:

输入的第一行给出城市数目N (1≤N≤10)和道路数目M和1(表示有向图)或0(表示无向图);

接下来的M行对应每个城市间来往所需时间,每行给出3个正整数,分别是两个城市的编号(从1编号到N)和来往两城市间所需时间。最后一行给出一个编号,表示从此编号地点出发。

输出格式:

输出从特定地点出发到达所有城市(按编号1-编号N顺序输出)的距离(用编号1->编号**: 表示 ),如果无路,请输出no path。每个城市占一行。

输入样例:

5 5 1
1 2 2
1 4 8
2 3 16
4 3 6
5 3 3
1

输出样例:

1->1:0
1->2:2
1->3:14
1->4:8
1->5:no path

思路

1.使用vector创建动态数组储存图,记得区分有向无向图;

2.dijkstra算法:

(1)源点集合S,初始源点为起点v

(2)需要将剩余n-1个点放入集合S表示完成任务

(2).1 循环n-1次找剩余n-1个源点

(2).2 找新源点s放入S(新源点就是dist[s]最小),标记新源点vis[s]=1;

(2).3更新距离初源点v的距离即dist[]:

找除了S里面的源点且与新源点s相连的点j,比较dist[s]+grap[s][j]和dist[j]的大小,然后更新。

代码

#include<bits/stdc++.h>
using namespace std;
#define ff 11
#define mmax INT_MAX

void dijkstra(int n,int v,vector<vector<int>>& grap){
    vector<int> vis(ff,0);
    vector<int> dist(ff,mmax);

    for(int i=1;i<=n;i++){
        if(grap[v][i]!=mmax){
            dist[i]=grap[v][i];
        }
    }
    vis[v]=1;
    dist[v]=0;
    
    for(int j=1;j<n;j++){
        int len=mmax;
        int s=v;
        for(int i=1;i<=n;i++){
            if(!vis[i]&&dist[i]<len){
                len=dist[i];
                s=i;
            }
        }
        vis[s]=1;

        for(int k=1;k<=n;k++){
            if(!vis[k]&&grap[s][k]!=mmax){
                int newlen=grap[s][k]+dist[s];
                if(newlen<dist[k]){
                    dist[k]=newlen;
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(dist[i]==mmax) cout<<v<<"->"<<i<<":no path"<<endl;
        else cout<<v<<"->"<<i<<":"<<dist[i]<<endl;
    }
}

int main(){
    int n,m,x;
    cin>>n>>m>>x;
    vector<vector<int>> grap(ff,vector<int>(ff,mmax));
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        grap[u][v]=w;
        if(!x){
            grap[v][u]=w;
        }
    }
    int start;
    cin>>start;
    dijkstra(n,start,grap);
}

扩展

输出路线:

在更新dist[]处添加:

for(int k=1;k<=n;k++){
            if(!vis[k]&&grap[s][k]!=mmax){
                int newlen=grap[s][k]+dist[s];
                if(newlen<dist[k]){
                    dist[k]=newlen;

                    pre[k]=s;
                }
            }

pre[k]=s表示k的前继点是s(!!!记得定义pre[]数组并初始化为0或者其他随便哈)

输出代码:

int end;//终点

int k=pre[end];

while(k!=0){            //因为我初始化了噻,前继点为0表示到头啦!

   cout<<k;

k=pre[k];

}

4.2删数问题

给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。如果数字最前面有0不输出。

输入格式:

第 1 行是1 个正整数 a。第 2 行是正整数k。

输出格式:

输出最小数。

输入样例:

在这里给出一组输入。例如:

178543 
4 
5001 
1
123456 
2
109 
1

输出样例:

在这里给出相应的输出。例如:

13
1
1234
9

思路

按照数字特点,从左往右,左边数字越小整体越小

所以两种情况:

(1)整数每个数字从左往右递减,那么减掉最右边的数字可以达到题目要求。

(2)如果整数每个数字无序,那边一共循环n次(删n个数字),找出非递减的数字(即左边数字大于右边数字)删掉即可。

最后:如删数后出现数字串为009等情况,记得抹零。

代码

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    string s;
    cin>>s>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<s.size();j++){
            if(s[j]>s[j+1]||j==s.size()-1){
                s.erase(s.begin()+j);
                break;
            }
        }
    }
    while(s[0]=='0') s.erase(s.begin());
    cout<<s;
    return 0;
}

4.3最优分解问题

设 n 是一个正整数。现在要求将 n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。

输入格式:

文件的第 1 行是正整数 n。

输出格式:

将计算出的最大乘积输出

输入样例:

10

输出样例:

30

思路

如果a+b=n,则|a-b|越小,那么ab越大,可以将n分解成从2开始的连续自然数的和,如果到某个数时不够分(比如下一个分解数是4,但因为分解完3只剩2),那么把2往会加(即原路返回每个加1,尽量减小|a-b|)

代码

#include<bits/stdc++.h>
using namespace std;

int find(int n){
    vector<int> a(2*n);
    if(n<=4) return n-1;

    int i=0;
    int k=2;
    while(n>=k){
        a[i]=k;
        i++;
        n-=k;
        k++;
    }
    int p=i;
    
    while(n!=0){
        a[i-1]++;
        n--;
        i--;
    }
    int num=1;
    for(int j=0;j<p;j++){
        num*=a[j];
    }
    return num;
}

int main(){
    int n;
    cin>>n;
    int mmax=find(n);
    cout<<mmax;
}

4.4 程序存储问题

设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是 li,1≤i≤n。 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序。 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数。

输入格式:

第一行是2 个正整数,分别表示文件个数n和磁带的长度L。接下来的1行中,有n个正整数,表示程序存放在磁带上的长度。

输出格式:

输出最多可以存储的程序数。

输入样例:

在这里给出一组输入。例如:

6 50 
2 3 13 8 80 20

输出样例:

在这里给出相应的输出。例如:

5

思路

需要放入最多的程序,即尽量安排空间需求小的程序。(排序从小到大)

代码

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,l;
    cin>>n>>l;
    vector<int> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a.begin(),a.end());

    int pp=a[0];
    int num=0;
    int i=0;
    while(l>0&&l>=pp){
        l-=pp;
        num++;
        i++;
        pp=a[i];
    }
    cout<<num;
}

扩展

vector数组排序:

1.从小到大

sort(name.begin(),name.end());

name.begin()表示指向数组头的迭代器,name.end()表示指向数组尾下一个位置的迭代器,该式表示将叫name的vector元素按从小到大进行升序排序。

2.从大到小

sort(name.rbegin(),name.rend());

name.rbegin()表示指向数组尾的迭代器,name.rend()表示指向数组头前一个位置的迭代器,该式表示将叫name的vector元素按从大到小进行降序排序。

 3.自定义

sort(res.begin(),res.end(),[&](const typename&a,const typename&b)->bool{
    return (输入你的排序标准);
});

4.5最优合并问题

给定k 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。
假设所采用的 2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较。试设
计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。

输入格式:

第一行有 1 个正整数k,表示有 k个待合并序列。
第二行有 k个正整数,表示 k个待合并序列的长度。

输出格式:

输出最多比较次数和最少比较次数。

输入样例:

在这里给出一组输入。例如:

4
5 12 11 2 

输出样例:

在这里给出相应的输出。例如:

78 52

思路

类似哈夫曼编码,最少比较即从较小个待合并序列开始合并,最多反之。

代码

#include<bits/stdc++.h>
using namespace std;

int mergemin(vector<int>& a,int n){
    int num=0;
    int m=n;
    while(m>1){
        m--;
        num+=(a[0]+a[1]-1);
        a[0]+=a[1];
        a.erase(a.begin()+1);
        sort(a.begin(),a.end());              //!!! 必须要sort,因为新合并的序列长度可能比后面的序列长度长。
    }
    return num;
}

int mergemax(vector<int>& a,int n){
    int num=0;
    int m=n;
    while(m>1){
        m--;
        num+=(a[0]+a[1]-1);
        a[0]+=a[1];
        a.erase(a.begin()+1);
        sort(a.rbegin(),a.rend());
    }
    return num;
}

int main(){
    int n;
    cin>>n;
    vector<int> a(n);
    vector<int> b(n);
    for(int i=0;i<n;i++) cin>>a[i];
    for(int j=0;j<n;j++) b[j]=a[j];

    sort(a.begin(),a.end());
    sort(b.rbegin(),b.rend());

    int mmax=mergemax(b,n);
    int mmin=mergemin(a,n);
    cout<<mmax<<" "<<mmin;
    return 0;
}

sort用法可以参考4.4的扩展

4.6排队接水

有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。

输入格式:

共两行,第一行为n(1≤n≤1000);第二行分别表示第1个人到第n个人每人的接水时间T1,T2,…,Tn,每个数据之间有1个空格。

输出格式:

输出为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

输入样例:

10
56 12 1 99 1000 234 33 55 99 812

输出样例:

291.90

思路

贪心算法:要使平均等待时间最短,即节水快的先接。

2等待1       !!!记得最后总时间要加上第一个人接水的时间喔

3等待1+2

4等待(1+2)+3

5等待(1+2+3)+4

.........

所以可以用循环合并n-2次(最后剩下两个不用合并噻)

注意开头和结尾噻!!!

代码 

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    int time=0;
    cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a.begin(),a.end());
    int p=a[0];
    while(a.size()>2){
        time+=(a[0]+a[1]);
        a[0]+=a[1];
        a.erase(a.begin()+1);
    }
    double aver=(double)(time+p)/n;
    cout<<fixed<<setprecision(2)<<aver;
}

4.7选点问题

数轴上有n个闭区间[ai, bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。

输入格式:

第一行一个数字n,表示有n个闭区间。
下面n行,每行包含2个数字,表示闭区间[ai, bi]

输出格式:

一个整数,表示至少需要几个点

输入样例:

在这里给出一组输入。例如:

3
1 3
2 4
5 6

输出样例:

在这里给出相应的输出。例如:

2

思路

题目就是解决用最少的点覆盖所有区间:即若有交集的区间,点放交集里头,没交集的区间单独开一个点丢进去。

如何定义是否交集?

1.先把区间按照end从小到达排序

2.以第一个区间end为标准end开始计数

3.如果下一个区间start<=end(说明交集,计数+1)

4.如果下一区间start>end(说明不交集),更新end

5.循环以上即可^_^

代码 

#include<bits/stdc++.h>
using namespace std;

struct qujian{
    int start;
    int end;
};

bool compare(const qujian&a,const qujian&b){
    return a.end<b.end;
}

int main(){
    int n;
    cin>>n;
    vector<qujian> qu(n);
    for(int i=0;i<n;i++){
        cin>>qu[i].start>>qu[i].end;
    }
    sort(qu.begin(),qu.end(),compare);

    int newend=qu[0].end;
    int num=1;
    for(int i=1;i<n;i++){
        if(qu[i].start>newend){
            num++;
            newend=qu[i].end;
        }
    }
    cout<<num;
}

4.8 汽车加油问题

一辆汽车加满油后可行驶 n公里。旅途中有若干个加油站。设计一个有效算法,指出应
在哪些加油站停靠加油,使沿途加油次数最少。

输入格式:

第一行有 2 个正整数n和 k(k<=1000 ),表示汽车加满油后可行驶n公里,且旅途中有 k个加油站。
第二行有 k+1 个整数,表示第 k 个加油站与第k-1 个加油站之间的距离。
第 0 个加油站表示出发地,汽车已加满油。
第 k+1 个加油站表示目的地。

输出格式:

输出最少加油次数。如果无法到达目的地,则输出“No Solution!”。

输入样例:

7 7
1 2 3 4 5 1 6 6 

输出样例:

4

思路

够油不加,不够就加呗

代码

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,k;
    cin>>n>>k;
    vector<int> d(k+1);
    for(int i=0;i<k+1;i++){
        cin>>d[i];
        if(d[i]>n){
            cout<<"No Solution!";
            return 0;
        }
    }

    int num=0;
    int len=n;
    for(int i=0;i<k+1;i++){
        if(len>d[i]){
            len-=d[i];
        }
        else{
            num++;
            len=n-d[i];
        }
    }
    cout<<num;
    return 0;
}

第五章(回溯)

5.1  0-1背包(n<=10)

给定n(n<=10)种物品和一个背包。物品i的重量是wi,价值为vi,背包的容量为C(C<=1000)。问:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有两个选择:装入或不装入。不能将物品i装入多次,也不能只装入部分物品i。可以不剪枝。

输入格式:

共有n+1行输入: 第一行为n值和c值,表示n件物品和背包容量c; 接下来的n行,每行有两个数据,分别表示第i(1≤i≤n)件物品的重量和价值。

输出格式:

输出装入背包中物品的最大总价值。

输入样例:

5 10
2 6
2 3
6 5
5 4
4 6

输出样例:

15

思路

01背包属于找最优解问题,用回溯法需要构造解的子集树,选为1,不选为0。可以顺序依次考虑每个物品,这样就形成了一棵解空间树: 基本思想就是遍历这棵树,以枚举所有情况,最后进行判断,如果重量不超过背包容量,且价值最大的话,该方案就是最后的答案。

!!!这是不剪枝方法,只适合物品较少的情况。

6b25f36627654b178c1b6f10b798fbd8.jpeg

59ee6ba7f71a4ea6a11aa7eb160b44fe.jpeg

  1. 逐层返回:当back(m)执行return时,控制权返回给调用它的back(m-1)back(m-1)会继续执行它自己的代码(如果有的话),在尝试放入或不放入索引为m-1的物品之后,它也会遇到一个return语句(可能是隐式的,即函数执行完毕自然返回),然后将控制权返回给back(m-2),依此类推。

  2. 回到初始调用点:最终,这个过程会一直持续到back(1)执行完毕并返回。此时,控制权返回到main函数中的back(1);之后的代码行。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 11; 

int n, c;
vector<int> weight(N), value(N); 
vector<int> vis(N, 0);
int maxvalue = 0;
int cv = 0, cw = 0;  

void back(int id){
    if(id>n){
        if(cv>maxvalue) maxvalue=cv;
        return;
    }

    if(cw+weight[id]<=c){
        cw+=weight[id];
        cv+=value[id];
        back(id+1);
        cw-=weight[id];
        cv-=value[id];
    }
    
    back(id+1);
}

int main() {
    cin >> n >> c;
    for (int i = 1; i <= n; i++) {
        cin >> weight[i] >> value[i];
    }
    back(1);  // 从第一个物品开始搜索
    cout << maxvalue << endl;
    return 0;
}

5.2 部落卫队问题

原始部落byteland中的居民们为了争抢有限的资源,经常发生冲突。几乎每个居民都有它的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍,并保证队伍中任何两个人都不是仇敌。

输入格式:

第一行两个正整数n和m,表示byteland部落中有n个居民,居民间有m个仇敌关系, 0<n<200, 0<m<6000。居民编号为1,2,…,n。接下来输入m行中,每行正整数u和v,表示居民u和居民v是仇敌。

输出格式:

输出部落卫队最佳组建方案中包含的居民人数。之后逐个输出卫队组成xi, 1<=i<=n, xi=0表示居民i不在卫队中,xi=1表示居民i在卫队中。

输入样例:

7 10
1 2
1 4
2 4
2 3
2 5
2 6
3 5
3 6
4 5
5 6

输出样例:

3
1 0 1 0 0 0 1 

思路

跟背包啥的一样

代码 

#include<bits/stdc++.h>
using namespace std;

int n,m;
vector<vector<int>> amy;
vector<int> xi;
vector<int> cxi;
int mmax=0;

void back(int id,int size){
    if(id>n){
        if(size>mmax){
            mmax=size;
        for(int i=1;i<=n;i++){
            xi[i]=cxi[i];
        }
        }
        return ;
    }

    int add=1;
    for(int j=1;j<id;j++){
        if(cxi[j]&&amy[id][j]){
            add=0;
            break;
        }
    }

//选

    if(add){
        cxi[id]=1;
        back(id+1,size+1);
        cxi[id]=0;
    }

//不选

    back(id+1,size);
}

int main(){
    cin>>n>>m;
    amy.resize(n+1,vector<int>(n+1,0));
    xi.resize(n+1);
    cxi.resize(n+1);
    for(int i=0;i<m;i++){
        int u,v;
        cin>>u>>v;
        amy[u][v]=1;
        amy[v][u]=1;
    }

    back(1,0);
    cout<<mmax<<endl;
    for(int i=1;i<=n;i++){
        cout<<xi[i]<<" ";
    }
    return 0;
}

5.3子集和问题

设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法,并输出利用回溯法在搜索树(按输入顺序建立)中找到的第一个解。

输入格式:

输入数据第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值。接下来的1行中,有n个正整数,表示集合S中的元素。
是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。

输出格式:

输出利用回溯法找到的第一个解,以空格分隔,最后一个输出的后面有空格。当问题无解时,输出“No Solution!”。

输入样例:

在这里给出一组输入。例如:

5 10
2 2 6 5 4

输出样例:

在这里给出相应的输出。例如:

2 2 6 

思路

回溯法找解:

1.题目说找到的第一个解,所以先选排在前面的元素,及按照元素顺序展开01完全二叉树,跟5.1,5.2题一样的。

2.回溯back(t,sum),t代表第x个元素,sum代表之前选了元素的总和。

3.回溯流程:

(1)选前判断:sum>m,回溯去掉不要它

(2)选前判断:sum=m,是我们要的结果,因为要第一个结果,所以需要flag标记。一旦找到第一个结果,一路回溯,回到main中的back结束回溯

(3)所有元素遍历完(t=n):如果sum=m,flag=1,一路回溯到main,如果sum<m,继续找。

(4)选

sum+;

记录此元素s1[t](t代表层数且第x个元素,所以可以直接用t)

后面回溯记得sum-且去掉s1[t]标记

(5)不选

直接t+1即可,sum不变

代码 

#include<bits/stdc++.h>
using namespace std;

int n,m;
vector<int> s;
vector<int> s1;
int flag=0;

void back(int t,int sum){
    if(sum>m) return;

    if(flag) return;
    
    if(t>n){
        if (sum == m) {
            for (int i = 1; i <=n; ++i) {
                if (s1[i]!=-1)
                    cout << s1[i] << " ";
            }
            flag = 1;
        }
        return;
    }
    
    //选
    sum+=s[t];
    s1[t]=s[t];
    back(t+1,sum);
    sum-=s[t];
    s1[t]=-1;

    //不选
    back(t+1,sum);
}

int main(){
    cin>>n>>m;
    s.resize(n+1);
    s1.resize(n+1,-1);
    int pp=0;
    for(int i=1;i<=n;i++){
        cin>>s[i];
        pp+=s[i];
    }

    if (pp < m) {
        cout << "No Solution!";
        return 0;
    }

    back(1,0);

    if (!flag)
    cout << "No Solution!";
    return 0;
}

5.4 旅行售货员

某售货员要到若干城市去推销商品,已知各城市之间的路程(或旅费)。他要选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程(或总旅费)最小。

输入格式:

第一行为城市数n

下面n行n列给出一个完全有向图,如 i 行 j 列表示第 i 个城市到第 j 个城市的距离。

输出格式:

一个数字,表示最短路程长度。

输入样例:

3
0 2 1
1 0 2
2 1 0

输出样例:

3

思路

有(n-1)!条可选路线

代码可以更简洁,当n过大时,最好剪枝,甚至回溯法不适合。

代码 

#include<bits/stdc++.h>
using namespace std;

int n;
vector<vector<int>> grap;
vector<int> x; // 存储当前路径上的城市
vector<int> vis;
int cl = 0;
int mminlen =INT_MAX;

void back(int t) {
    if (t==n) {
        if(cl+grap[x[n-1]][0]<mminlen) mminlen=cl+grap[x[n-1]][0];
        return;
    }

    for(int i=0;i<n;i++){
        if (!vis[i]&&grap[x[t-1]][i] != 0){
            cl += grap[x[t-1]][i];
            x[t] = i;
            vis[i] =1;
            cout<<t<<":"<<i<<endl;
            back(t + 1);
            vis[i] =0;
            cl -= grap[x[t-1]][i];
            cout<<" back:"<<i<<endl;
        } 
    }
}

int main() {
    cin >> n;
    grap.resize(n, vector<int>(n, 0));
    x.resize(n);
    vis.resize(n,0);

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>grap[i][j];
        }
    }

    x[0] = 0;
    vis[0] =1;


    if(n==1){
        cout<<0;
        return 0;
    }
    
    back(1);
    cout << mminlen << endl;

    return 0;
}

5.5 工作分配问题

设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为cij 。 设计一个算法,对于给定的工作费用,为每一个人都分配1 件不同的工作,并使总费用达到最小。

输入格式:

输入数据的第一行有1 个正整数n (1≤n≤20)。接下来的n行,每行n个数,表示工作费用。

输出格式:

将计算出的最小总费用输出到屏幕。

输入样例:

在这里给出一组输入。例如:

3
10 2 3
2 3 4
3 4 5

输出样例:

在这里给出相应的输出。例如:

9

思路

跟5.4一样的原理:

1.一个大for控制第一层元素的选择

2.没标记就选

3.到底回溯

(自己悟)

这个要剪枝,因为n一旦大了就超时。

// 剪枝条件:如果这个人已经被分配了工作,或者当前分配已经比已知最小成本还差,则跳过
      if(vis[j]||cfree+fre[t][j]>=mmin){
            continue;
        }

代码

#include<bits/stdc++.h>
using namespace std;

int n;
vector<vector<int>> fre;
vector<int> vis;
int mmin=INT_MAX;
int cfree=0;

void back(int t){

    if(t>n){
        if(cfree<mmin) mmin=cfree;
        return;
    }
    
    for(int j=1;j<=n;j++){

        if(vis[j]||cfree+fre[t][j]>=mmin){
            continue;
        }
        
        if(!vis[j]){
            cfree+=fre[t][j];
            vis[j]=1;
            back(t+1);
            cfree-=fre[t][j];
            vis[j]=0;
        }
    }
}

int main(){
    cin>>n;
    fre.resize(n+1,vector<int>(n+1));
    vis.resize(n+1,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>fre[i][j];

    back(1);
    cout<<mmin;
    return 0;
}


http://www.mrgr.cn/news/78425.html

相关文章:

  • org.apache.log4j的日志记录级别和基础使用Demo
  • ES6中,Set和Map的区别 ?
  • 如何选择最适合企业的ETL解决方案?
  • HarmonyOs鸿蒙开发实战(21)=>组件间通信@ohos/liveeventbus
  • 如何穿透模糊,还原图片真实面貌
  • [SWPUCTF 2021 新生赛]error
  • 面试手撕题积累
  • 在 Spring Boot 中构造 API 响应的最佳实践
  • 彻底理解微服务配置中心的作用
  • PyQt学习笔记
  • (长期更新)《零基础入门 ArcGIS(ArcMap) 》实验二----网络分析(超超超详细!!!)
  • android集成FFmpeg步骤以及常用命令,踩坑经历
  • 【Leetcode 每日一题】743. 网络延迟时间
  • 使用ENSP实现NAT
  • PostgreSQL 三种关库模式
  • CTO 实际上是在做什么?
  • LLamafactory API部署与使用异步方式 API 调用优化大模型推理效率
  • 矩阵重新排列——sort函数
  • 使用ENSP实现默认路由
  • 蓝桥杯c++算法秒杀【6】之动态规划【上】(数字三角形、砝码称重(背包问题)、括号序列、组合数问题:::非常典型的必刷例题!!!)
  • 鸿蒙NEXT元服务:利用App Linking实现无缝跳转与二维码拉起
  • 【Leetcode Top 100】48. 旋转图像
  • 微信小程序按字母顺序渲染城市 功能实现详细讲解
  • ThingsBoard规则链节点:GCP Pub/Sub 节点详解
  • 技术文档的规划布局:构建清晰的知识蓝图
  • 【Leetcode 每日一题】632. 最小区间