B.牛牛的DRB迷宫II
题解
看到构造题就傻眼了,当时脑子一直在想组合数的方法.....
事后问了学长,由于这是一个方案叠加,所以我们通过拆二进制的方法来解决这个问题
1 1 1 1
1 1 1 2
1 1 2 4
1 2 4 8
这个就是我们构造的2的幂的解。那么剩下的呢,举个例子吧,比如是11
1 1 1 1 1
1 1 1 2 3
1 1 2 4 3
1 2 4 8 11
因为语言难以描述,所以我就不描述了
学长说构造题拆二进制是常见思路,那我就先记下吧
#include<bits/stdc++.h> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) typedef long long LL; typedef pair<int,int> PII; #define X first #define Y second inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } int x,len=1,dp[50][50],i,j,k; char a[52][52]; int main() { x=read(); if(!x)x=1000000007; for(i=31;i>=0;i--)if(x>>i)break; printf("%d %d\n",i+1,i+2); for(j=0;j<i+1;j++)for(k=0;k<i+2;k++)a[j][k]='B'; for(k=0;k<i+2;k++)a[i][k]='R'; for(j=1;j<i;j++)for(k=0;k<i-j;k++)a[j][k]='D'; for(j=0;j<=i;j++)a[j][i+1]='D'; for(j=0;j<i;j++)if(x>>j&1)a[j][i]='B';else a[j][i]='D'; for(j=0;j<i+1;j++)printf("%s\n",a[j]); return 0; }
E.牛牛的随机数
题解
根据套路肯定是算每个二进制位对答案的贡献,那么我们只需要求一个函数\(f(x,i)\) 表示在\([1,x]\) 区间内二进制位\(i\) 出现了多少次1,然后将贡献叠加即可。
(这个所谓的函数虽然就几行,但是好难写)
J.牛牛的宝可梦Go
题解
我开始想了一个\(O(m*n^2)\) 的做法,是设\(dp[i][j]\) 表示当前在\(i\) 时间,在\(j\) 城市的最大值,但是转移是\(O(n)\) 的,所以不行
换一个思路\(DP\) 设\(dp[i]\) 表示当前捕捉了神奇宝贝\(i\) 的最大价值,转移的话就从最近200个开始转移,因为200个以外的,都距离超过200个时间了,必能走到、
细节1:图可能不联通(这个意识到了)
细节2:\(dp\) 数组应该先设为\(-oo\) ,要不然有可能从不合法的地方继承过来(死于此)
#include<bits/stdc++.h> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) typedef long long LL; typedef pair<int,int> PII; #define X first #define Y second inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const int maxn=210,maxm=100010; int n,m,u,v,w,tot,dis[maxn][maxn]; LL dp[maxm],ans;//dp[i][j]表示当前在i城市,j时间的最大值 struct Pokemon { int t,p,val; Pokemon() {} Pokemon(int _1,int _2,int _3):t(_1),p(_2),val(_3) {} bool operator < (const Pokemon &s)const {return t<s.t;} }a[maxm]; int main() { mem(dis,42); n=read();m=read(); while(m--)u=read(),v=read(),dis[u][v]=dis[v][u]=1; for(int i=1;i<=n;i++)dis[i][i]=0; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); m=read(); for(int i=1;i<=m;i++) { u=read(),v=read(),w=read(); if(dis[1][v]>500)continue; a[++tot]=Pokemon(u,v,w); } m=tot; sort(a+1,a+m+1); a[0].p=1; for(int i=1;i<=m;i++)dp[i]=-1ll<<60; for(int i=1;i<=m;i++) for(int j=i-1;j>=max(0,i-500);j--) if(dis[a[i].p][a[j].p]<=a[i].t-a[j].t)dp[i]=max(dp[i],dp[j]+a[i].val); for(int i=0;i<=m;i++)ans=max(ans,dp[i]); printf("%lld\n",ans); return 0; }
废话
细节杀我
来源:https://www.cnblogs.com/FYH-SSGSS/p/12285373.html