过题状况c++
第一题:100%
第二题:100%
第三题:100%
第四题:100%
第五题:100%web
第一题
svg
经典区间dp问题,dp[i][j]表明着从字符串i位置到j位置须要的最小括号匹配数,若是第i个位置和第j个位置的两个括号是匹配的,那么dp[i][j] = dp[i+1][j-1],至关于两边分别往里缩了一个;当i<j时,dp[i][j] = dp[i][k]+dp[k+1][j] ;ui
#include<bits/stdc++.h> using namespace std; const int maxn=222; int dp[maxn][maxn]; int main(){ string s;cin>>s; int len=s.length(); for(int i=0;i<len;i++) dp[i][i]=1; for(int l = 1; l < len; l++){ for(int i = 0; i < len - l; i++){ int j = i + l; dp[i][j]=len; if((s[i]=='[' && s[j]==']') || (s[i]=='(' && s[j]==')')) dp[i][j] = min(dp[i][j], dp[i+1][j-1]); for(int k = i; k < j; k++) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]); } } printf("%d\n",dp[0][len-1]); }
第二题:
spa
学太高数的都会,简单的一个积分题3d
#include<bits/stdc++.h> using namespace std; double solve(double a, double b, double x){ return a*x*x*x/3+x*x/2+b*x; } int main(){ int T;scanf("%d",&T); while(T--){ double A,B,C,D; cin>>A>>B>>C>>D; double ans=solve(A,B,D)-solve(A,B,C); printf("%lf\n",ans); } }
第三题:
code
很简单答案为C(n,1)*1+C(n,2)*2+C(n,3)*3…,看到这是否是很熟悉了
ans=C(n,0)*0+C(n,1)*1+C(n,2)*2+C(n,3)3…+C(n,n)n 正着写
ans=C(n,n)n+C(n,n-1)(n-1)+… 反着写
两个加起来2ans=n2^n
ans=n2^(n-1)便可,用快速幂xml
#include<bits/stdc++.h> using namespace std; const int mod=1e9+7; long long quick_pow(long long a,long long b){ long long ans=1; while(b){ if(b&1)ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int main(){ long long n; cin>>n; cout<<n*quick_pow(2, n-1)%mod<<endl; }
第四题:
blog
STL大法好,set+map轻松作到排序+计数排序
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+200; set<int>g[maxn]; int main(){ int n,m; scanf("%d%d",&n,&m); while(m--){ int x,y; scanf("%d%d",&x,&y); g[x].insert(y); g[y].insert(x); } map<set<int>, int>q; for(int i=1;i<=n;i++) if(g[i].size()!=0) q[g[i]]+=1; long long ans=0; map<set<int>, int>::iterator it; for(it=q.begin();it!=q.end();it++){ int num=it->second; if(num>1) ans+=1ll*num*(num-1)/2; } cout<<ans<<endl; }
第五题
很简单的想法,最短路便可,注意!!!坑点在于有重边,我还暴力写了个dfs+剪枝,过了55%
最短路
#include<bits/stdc++.h> using namespace std; const int INF=1e9; const int maxn=2222; int v[maxn]; int dis[maxn], a[maxn][maxn]; int n,m,k; void Dj() { for (int i = 2; i <= n; i++) dis[i] = INF; dis[1] = 0; memset(v, 0, sizeof(v)); for (int i = 1; i <= n; i++) { int u = -1, minn = INF; for (int j = 1; j <= n;j++) if (v[j] == 0 && dis[j] < minn) { minn = dis[j]; u = j; } if(u==-1) break; v[u] = 1; for (int j = 1; j <= n; j++) if (v[j] == 0)dis[j] = min(dis[j], dis[u] + a[u][j]); } } int main(){ cin>>n>>m>>k; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=INF; while(m--){ int x,y,z; scanf("%d%d%d",&x,&y,&z); a[x][y]=min(a[x][y],z); a[y][x]=min(a[y][x],z); } while(k--){ int x,y; scanf("%d%d",&x,&y); a[x][y]=0; } Dj(); if(dis[n]==INF) dis[n]=-1; cout<<dis[n]<<endl; }
暴力dfs
#include<bits/stdc++.h> using namespace std; const int maxn=2222; vector<pair<int,int> >G[maxn]; vector<int>K[maxn]; int n,m,k,ans=1e9; int vis[maxn]; void dfs(int u,int fa,int step){ if(u==n){ if(step<ans) ans=step; return; } if(step>=ans) return; for(int i=0;i<K[u].size();i++){ int v=K[u][i]; if(v==fa||vis[v]) continue; vis[v]=1; dfs(v,u,step); vis[v]=0; } for(int i=0;i<G[u].size();i++){ int v=G[u][i].first, w=G[u][i].second; if(v==fa||vis[v]) continue; vis[v]=1; dfs(v,u,step+w); vis[v]=0; } } int main(){ cin>>n>>m>>k; while(m--){ int x,y,z; scanf("%d%d%d",&x,&y,&z); G[x].push_back(make_pair(y,z)); G[y].push_back(make_pair(x,z)); } while(k--){ int x,y; scanf("%d%d",&x,&y); K[x].push_back(y); } vis[1]=1; dfs(1,0,0); if(ans==1e9) ans=-1; cout<<ans<<endl; }