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;