版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}