22.4.10

1,滑雪(记忆化搜索)2,倒数第n个字符串,3,猜数字;4,阅览室;5,点赞狂魔,6,小字辈;


1,滑雪(记忆化搜索)

题意:

直接dfs会爆tle,所以用dp来做;

闫式dp分析法:
第一步:

状态表示:

f[ i, j ] 表示从当前位置开始滑能滑到的最远路径;

属性:max

第二步:

状态计算:
先划分集合:
很明显,根据集合定义可以划分为四个部分:

然后计算子集:

拿向上滑举例:

i , j → (滑到) i-1 , j → .. .. . . .只有第一步滑到 i-1 ,j 是确定的,剩下的都确定,又因为求的是最大值,把每个集合都减1对答案没有影响,所以可以把第一步去掉来看,就是从i-1 , j 滑到的 最远距离,即f[ i-1 ,j ] 同理可以得到四个子集;

注意,4个子集并不是每个都存在,必须满足边界和高度条件;

所以答案就是对每个f[ i , j ] 取max,就是最远的;

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=300+10;
int f[N][N];
int a[N][N];
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
int r,c;
int ans;
int dp(int x,int y)
{
	if(f[x][y])return f[x][y];
	f[x][y]=1;
	rep2(i,0,3)
	{
		int x1=x+dx[i];
		int y1=y+dy[i];
		if(x1>0&&x1<=r&&y1>0&&y1<=c&&a[x1][y1]<a[x][y])
		{
			f[x][y]=max(f[x][y],dp(x1,y1)+1);
		}
	}
	return f[x][y];
}
signed main()
{
	quick_cin();
	cin>>r>>c;
	rep2(i,1,r)
	 rep2(j,1,c)cin>>a[i][j];
	memset(f,0,sizeof f);
	rep2(i,1,r)
	{
	 	rep2(j,1,c)
	 	{
	 		ans=max(ans,dp(i,j));
		}
	}
	cout<<ans;	
	return 0;
}     

思考:如果从dfs角度来理解优化:对于每个点都需要dfs是肯定的,但是问题在于进入dfs后,搜到了一个点,之前计算过,我们没必要计算了其实,假如从(2,4)搜到(2,3),我们如果算过了(2,3)这个点,那么再次碰到它时直接调用它的值就行,没有必要再算,所以需要f[][]来储存算过的值,搜到了直接调用就行;

所以深度搜索+dp优化-》记忆化搜索(递归式动态规划);

2,倒数第n个字符串

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
int l,n;
char s[7];
signed main()
{
    quick_cin();
	cin>>l>>n;
	ll m=pow(26,l)-n;
	int k=0;
	rep1(i,0,l)
	{
		s[k++]=m%26+'a';
		m/=26;
	}
	per2(i,k-1,0)printf("%c",s[i]);
    return 0;
}

3,猜数字

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e4+10;
int n;
struct ji
{
	string name;
	int num;
	int cha;
}a[N];
bool cmp(ji a,ji b)
{
	return a.cha<b.cha;
}
signed main()
{
	quick_cin();
	cin>>n;
	int sum=0;
	rep2(i,1,n)
	{
		cin>>a[i].name>>a[i].num;
		sum+=a[i].num;
	}
	int ans=sum/n/2;
	rep2(i,1,n)
	{
		a[i].cha=abs(a[i].num-ans);
	}
	sort(a+1,a+n+1,cmp);
	cout<<ans<<" "<<a[1].name;
    return 0;
}

4,阅览室

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e3+10;
int n,x,hour,minute;
int tim[N],sum,cs;
bool flag[N];
signed main()
{
//	quick_cin();
	cin>>n;
	char c;
	while(n)
	{	
		memset(flag,0,sizeof flag);
		memset(tim,0,sizeof tim);
		sum=0,cs=0;
		while(scanf("%d %c %d:%d",&x,&c,&hour,&minute))
		{
			if(x==0)
			{
				break;
			}
			if(c=='S')
			{
				tim[x]=hour*60+minute;
				flag[x]=1;
			}
			else
			{
				if(flag[x]==1)
				{
					flag[x]=0;
					sum+=hour*60+minute-tim[x];
					cs++;
				}
			}
		}
		n--;
		if(cs==0)cout<<0<<" "<<0<<endl;
		else printf("%d %.0f\n",cs,(db)sum/cs);
	}
    return 0;
}

5,点赞狂魔

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e3+10;
int n;
struct ji
{
	string name;
	ll sum;
	int cs;
}a[N];
bool cmp(ji a,ji b)
{
	if(a.cs!=b.cs)return a.cs>b.cs;
	return a.sum<b.sum;
}
signed main()
{
	quick_cin();
	int n;
	cin>>n;
	rep2(i,1,n)
	{
		cin>>a[i].name;
		int k;
		cin>>k;
		ll num=0;
		int p=0;
		unordered_map<int,int>hs;
		rep2(j,1,k)
		{	
			int x;cin>>x;
			num+=x;
			if(hs[x]==0)
			{
				hs[x]=1;
				p++;
			}
		}
		a[i].sum=k-p;
		a[i].cs=p;
	//	cout<<p<<endl;
	}
	sort(a+1,a+n+1,cmp);
	cout<<a[1].name;
	rep2(i,2,3)
	{
		if(a[i].cs)cout<<" "<<a[i].name;
		else cout<<" "<<"-";
	}
    return 0;
}

6,小字辈(24分);

注意添加边的顺序(父子关系)和高度的求法;

高度的求法很好的符合了题意,因为可以把每个点的高度求出来,这样对各个点的操作也很好;

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e5+10;
int n,root;
int e[N],ne[N],h[N],idx;
int dg[N];
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs()
{
	queue<int>q;
	q.push(root);
	int maxdg=1;//初始化为0是错的,本来含义上也该是1;
	dg[root]=1;
	while(q.size())
	{
		int t=q.front();q.pop();
		for(int i=h[t];i!=-1;i=ne[i])
		{
			q.push(e[i]);
			dg[e[i]]=dg[t]+1;
			if(dg[e[i]]>maxdg)maxdg=dg[e[i]];
		}
	}
	cout<<maxdg<<endl;
	bool flag=0;
	rep2(i,1,n)
	{
		if(!flag)
		{
			if(maxdg==dg[i])
			{
				cout<<i;
				flag=1;
			}
		}
		else
		{
			if(maxdg==dg[i])cout<<" "<<i;
		}
	}
}
signed main()
{
	quick_cin();
	cin>>n;
	memset(h,-1,sizeof h);
	rep2(i,1,n)
	{
		int x;
		cin>>x;
		if(x!=-1)add(x,i);
		else root=i;
	}
	bfs();
    return 0;
}

25分了,把maxdg初始化为1,不能是0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dull丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值