算法实验课

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37428263/article/details/80113568

ps:开玩笑的,请随意

1.格雷码构造问题 (分治法)

//分治法
/*the sample input:
4
the sample output:
1111
0111
0011
1011
1001
0001
0101
1101
1100
0100
0000
1000
1010
0010
0110
1110
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=3000+5;
char s[maxn][maxn];
void gray(int row,int n)
{
    if(row==1) return;
    for(int i=0;i<row/2;i++)
    {
        s[i][n-1]='1';
        s[row-1-i][n-1]='0';
    }
    gray(row/2,n-1);
    for(int i=row/2;i<row;i++)
        for(int j=0;j<n-1;j++)
             s[i][j]=s[row-1-i][j];
}
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        int row=1<<n;               //行数
        gray(row,n);
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<n;j++)
                printf("%c",s[i][j]);
            printf("\n");
        }
    }
    return 0;
}

2.dp 最大子段和问题

//dp
/*the sample input:
6
-2 11 -4 13 -5 -2
the sample output:
20
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=100+5;
int dp[maxn];
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        int res=-1;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        {
            int t;
            scanf("%d",&t);
            dp[i+1]=max(dp[i]+t,t);
            res=max(res,dp[i+1]);
        }
        printf("%d\n",res);
    }
    return 0;
}

3.最小延迟调度问题

//贪心策略
/*the sample input:
5
5 8 4 10 3
10 12 15 11 20
the sample output:
12
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+5;
typedef pair<int,int>PII;
int T[maxn];                //预计服务时长
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        priority_queue<PII,vector<PII>,greater<PII> >pq;
        while(!pq.empty()) pq.pop();
        for(int i=0;i<n;i++)
            scanf("%d",&T[i]);
        for(int i=0;i<n;i++)
        {
             int t;
             scanf("%d",&t);                        //期望结束时刻
             pq.push(PII(t,T[i]));
        }
        int t=0,res=0;
        while(!pq.empty())
        {
            PII p=pq.top();
            pq.pop();
            if(t+p.second>p.first) res=max(res,t+p.second-p.first);
            t+=p.second;
        }
        printf("%d\n",res);
    }
    return 0;
}

4.排兵布阵问题

//dfs递归枚举+剪枝
/*the sample input:
5
60 40 80 50 60
90 60 80 70 20
30 50 40 50 80
90 40 30 70 90
60 80 90 60 50
the sample output:
(0,2)
(1,0)
(2,4)
(3,3)
(4,1)
400
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=50+5;
int maze[maxn][maxn],C[maxn],n,sum,m[maxn],solve[maxn];
bool done[maxn];
void dfs(int cur,int k)           //填入位置
{
    if(cur==n) {
        if(k>sum) {
            memcpy(solve,C,sizeof(C));
            sum=k;
        }
        return;
    }
    //剪枝:如果当前产生的攻击力+剩余士兵能够产生的最大攻击力<=sum时,剪枝
    int k1=k;
    for(int i=cur;i<n;i++)
    {
        k1+=m[i];
    }
    if(k1<=sum) return;
    for(int i=0;i<n;i++)
    {
        if(!done[i]) {
            C[cur]=i;
            done[i]=true;
            dfs(cur+1,k+maze[cur][i]);
            done[i]=false;
        }
    }
}
int main()
{
    while(scanf("%d",&n)==1&&n)
    {
        memset(done,false,sizeof(done));
        memset(m,0,sizeof(m));
        sum=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&maze[i][j]);                        //i士兵在防卫点的攻击力
                m[i]=max(m[i],maze[i][j]);
            }
        }
        dfs(0,0);
        for(int i=0;i<n;i++)
            printf("(%d,%d)\n",i,solve[i]);
        printf("%d\n",sum);
    }
    return 0;
}

5.运动员最佳匹配问题

//匹配问题   递归枚举 
/*the sample input:
5
60 40 80 50 60
90 60 80 70 20
30 50 40 50 80
90 40 30 70 90
60 80 90 60 50
23 20 14 52 16
25 14 48 98 74
1 5 45 98 47
10 25 56 97 41
20 25 18 75 94
the sample output:
the (man,woman):
(0,0)
(1,3)
(2,2)
(3,4)
(4,1)
17600
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=100+5;
int P[maxn][maxn],Q[maxn][maxn],n,C[maxn],solve[maxn],sum; 
bool done[maxn];
void dfs(int cur,int k)
{
	if(cur==n) {
		if(k>sum) {
			memcpy(solve,C,sizeof(C));
			sum=k;
		}
		return;
	}
	for(int i=0;i<n;i++)
	{
		if(!done[i]) {
			done[i]=true;
			C[cur]=i;
			dfs(cur+1,k+P[cur][i]*Q[i][cur]);
			done[i]=false;
		}
	}
}
int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	while(scanf("%d",&n)==1&&n)
	{
		memset(done,false,sizeof(done));
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
			    scanf("%d",&P[i][j]);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				scanf("%d",&Q[i][j]);
		//判断最佳配对,使得各组男女双方总体竞赛优势总和达到最大
		sum=0;
		dfs(0,0);
		printf("the (man,woman):\n");
		for(int i=0;i<n;i++)
			printf("(%d,%d)\n",i,solve[i]);
		cout<<sum<<endl; 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37428263/article/details/80113568