对于该问题,首先是个迷宫问题,于是先考虑暴力求解,对于暴力来说,有这样一种方法: 对于任何一点来说,都可以进行选或者不选,然后当走到终点时如果符合条件则答案加 $1$,这样做的时间复杂度是 $2^n 也就是 2^50$,很明显得不到满分. 既然是迷宫那么可以考虑记忆化搜索,多加入两维数组,分别是当前的最大值和当前选择的数量,那么我们可以在搜索的过程中大大减少时间损耗
#include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; int mp[100][100],n,m,k; int dx[]={0,1},dy[]={1,0}; int dp[100][100][15][15]; int dfs(int x,int y,int num,int now){ if(x>n||y>m) return 0; if(dp[x][y][num][now]!=-1) return dp[x][y][num][now]; int res=0; if(x==n&&y==m){ if(num==k||((num==k-1)&&mp[x][y]>now)) res++; } else{ res+=dfs(x+1,y,num,now)%mod+dfs(x,y+1,num,now)%mod; if(mp[x][y]>now) res+=dfs(x+1,y,num+1,mp[x][y])%mod+dfs(x,y+1,num+1,mp[x][y])%mod; } dp[x][y][num][now]=res%mod; return dp[x][y][num][now]; } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m>>k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mp[i][j]; memset(dp,-1,sizeof dp); cout<<dfs(1,1,0,-1); return 0; }
首先考虑什么情况下为 $INF$,很明显如果所有的数之间都能互相整除,也就是说任何一个数都能由另一个数变换而来,这种情况一定会出现无限多,否则考虑有限,由于 $N<100$ 所以考虑枚举,进行背包规划,算出 $100000$ 以内可以被组成的数,输出不可被组成的数目即可,那么为什么这样是正确的呢?
在数论中,裴蜀定理是一个关于最大公约数(或最大公约式)的定理。裴蜀定理得名于法国数学家艾蒂安·裴蜀,说明了对任何整数 $a$、$b$ 和它们的最大公约数 $d = \gcd(a, b)$,关于未知数 $x$ 和 $y$ 的线性丢番图方程
$$ax + by = m$$
有解当且仅当 $d | m$。裴蜀等式有解时必然有无穷多个整数解。
特别来说,方程 $ax + by = 1$ 有解当且仅当整数 $a$ 和 $b$ 互素。对于多个整数而言,情况是类似的。
#include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; bool dp[N]; signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int n,num,res=0; cin>>n>>num; vector<int>a(n+1); a[1]=num,dp[0]=1,dp[a[1]]=true; for(int i=2;i<=n;i++){ cin>>a[i]; num=__gcd(num,a[i]),dp[a[i]]=true; } if(num>1) return cout<<"INF"<<endl,0; for(int i=1;i<=100000;i++) for(int j=1;j<=n;j++) if(dp[i]) dp[i+a[j]]=true; for(int i=1;i<=100000;i++) if(!dp[i]) res++; cout<<res; return 0; }
由于数据范围,考虑枚举每一个点,对于每一个点,计算出其它所有点到达这个点所需要的时间,然后进行更新答案即可
#include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; struct node{ int x,y,vx,vy; }p[N]; signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int n,res=0; cin>>n; for(int i=1;i<=n;i++){ int a,b,c; char d; cin>>a>>b>>c>>d; if(d=='L'||d=='R') p[i]={a,b,(d=='R'?c:-c),0}; else p[i]={a,b,0,(d=='U'?c:-c)}; } for(int i=1;i<=n;i++){ map<int,int>mp; int cnt=1; for(int j=1;j<=n;j++){ if(i==j) continue; int dx=p[j].x-p[i].x,dv=p[i].vx-p[j].vx; if(!dv){ if(!dx) cnt++; res=max(res,cnt); continue; } int t=dx/dv; if(dx%dv||t<0) continue; mp[t]++,res=max(res,mp[t]+cnt); } } for(int i=1;i<=n;i++){ map<int,int>mp; int cnt=1; for(int j=1;j<=n;j++){ if(i==j) continue; int dy=p[j].y-p[i].y,dv=p[i].vy-p[j].vy; if(!dv){ if(!dy) cnt++; res=max(res,cnt); continue; } int t=dy/dv; if(dy%dv||t<0) continue; mp[t]++,res=max(res,mp[t]+cnt); } } cout<<res<<endl; return 0; }
概率论基础
#include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; bool vis[N]; struct node{ int id; double w; bool operator<(const node&W)const{ if(w==W.w) return id<W.id; return w>W.w; } }p[N]; signed main() { int n,m,q; cin>>n>>m; double sum=0; vector<double>a(n+1); vector<vector<double>>b(n+1,vector<double>(m+1)); for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>b[i][j]; cin>>q; while(q--){ int x; cin>>x; vis[x]=true; } for(int i=1;i<=n;i++){ double now=a[i]; for(int j=1;j<=m;j++){ if(vis[j]) now*=b[i][j]; else now*=(100-b[i][j]); } sum+=now,a[i]=now; } for(int i=1;i<=n;i++) p[i]={i,a[i]/sum*100}; sort(p+1,p+1+n); for(int i=1;i<=n;i++) printf("%d %.2lf\n",p[i].id,p[i].w); return 0; }
标签:int,cin,备战,蓝桥,num,now,dp,mod From: https://www.cnblogs.com/o-Sakurajimamai-o/p/18038360