D题
给你n个正整数,n<=5,每个正整数大小不超过1000,最初
sum=0
s
u
m
=
0
,每次可将
sum
s
u
m
按顺序加上数组中的数,加完之后可以对sum的数位进行全排列,求最终能达到的最大值。
由于n只有5,所以按照题意模拟dfs实现就可以了,注意最后一组也可以按数位进行全排列。
D题代码
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 10;
int n;
int a[maxn];
int b[5];
int ans;
void dfs(int x,int sum)
{
if(x==n)
{
int xx=sum;
int pos=0;
while(xx)
{
b[pos++]=xx%10;
xx/=10;
}
sort(b,b+pos);
do
{
int cnt=0;
for(int i=0;i<pos;i++)
{
cnt=cnt*10+b[i];
}
ans=max(ans,cnt);;
}while (next_permutation(b,b+pos));
return ;
}
int b[5];
memset(b,0,sizeof(b));
int xx=sum;
int pos=0;
while(xx)
{
b[pos++]=xx%10;
xx/=10;
}
sort(b,b+pos);
do
{
int cnt=0;
for(int i=0;i<pos;i++)
{
cnt=cnt*10+b[i];
}
dfs(x+1,cnt+a[x]);
}while (next_permutation(b,b+pos));
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
dfs(0,0);
printf("%d\n",ans);
return 0;
}
E题
给你一些长度不等宽度相等的木板,横向左对齐依次排好,每次只能沿一条连续的直线进行粉刷,求最少多少次就能全部粉刷。
这算是我的第一分治题,由于之前没有接触过卡了很久,后来研究了一下,这个还是具有局部最优解的,如果当前所有木板中最短长度为t,共n个木板,若选择横向涂,则结果一定为n,若选择纵向涂,则将所有木板与最短木板相应的部分涂色,再对最短木板的左右分别进行下一轮的涂色问题。
E题代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 3005;
const int INF = 0x3f3f3f3f;
int n;
int a[maxn];
int dfs(int l,int r,int h)
{
if(l>r) return 0;
int ans=INF;
int sum=0;
int flag;
for(int i=l; i<=r; i++)
{
if(a[i]<ans) flag=i;
ans=min(a[i],ans);
if(a[i]>h) sum++;
}
int tmp=a[flag]-h;
if(tmp<0) tmp=0;
return min(sum,dfs(l,flag-1,max(a[flag],h))+dfs(flag+1,r,max(a[flag],h))+tmp);
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
int ans=dfs(1,n,0);
printf("%d\n",ans);
return 0;
}