1013考試總結
阿新 • • 發佈:2020-10-13
T1
一開始考慮先找到極大,然後擴充套件,發現極大並不能找到最大,就直接列舉狀態狀壓了
正解:直接暴力判斷當前點可以屬於哪個集合,為啥時間能過,不知道
#include <cstdio> #include <cstring> using namespace std; int n,m; bool cot[1010][1010]; long long ans; int cnt1,cnt2,num1[100010],num2[100010]; void dfs(int x) { if(x==n+1) { ans+=(cnt1&&cnt2); return ; } { bool flag=1; for(int i=1;i<=cnt1;i++) if(cot[x][num1[i]]) {flag=0;break;} if(flag) { num1[++cnt1]=x; dfs(x+1); cnt1--; } } { bool flag=1; for(int i=1;i<=cnt2;i++) if(!cot[x][num2[i]]) {flag=0;break;} if(flag) { num2[++cnt2]=x; dfs(x+1); cnt2--; } } } int main() { int t; scanf("%d",&t); while(t--) { ans=0; scanf("%d%d",&n,&m); memset(cot,0,sizeof(cot)); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); cot[a][b]=cot[b][a]=1; } dfs(1); printf("%lld\n",ans); } }
T2
一個像博弈論的題,實際上就是一個區域性最優匯出全域性的貪心
考慮A肯定會選擇最大字尾,很容易預處理出某一個字尾範圍的最大字尾
然後考慮維護字首最大值,這就是N選擇區域過後A會剩下給他的,列舉每一個可以的端點就行了,錯誤原因是沒有注意到端點可以選擇在 0 的位置
#include <cstdio> #include <algorithm> using namespace std; long long a[1000010],sur[1000010],suf[1000010],sum1[1000010],sum2[1000010],ans=-3e18; long long n,A,B; int main() { //freopen("game.in",r,stdin); //freopen("game.out",w,stdout); scanf("%lld%lld%lld",&n,&A,&B); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) sum1[i]=sum1[i-1]+A*a[i]; for(int i=1;i<=n;i++) sur[i]=max(sur[i-1],sum1[i]); for(int i=n;i>=1;i--) sum2[i]=sum2[i+1]+a[i]; for(int i=n;i>=1;i--) suf[i]=max(suf[i+1],sum2[i]); for(int i=1;i<=n;i++) ans=max(ans,-sum1[i]+sum2[i+1]-(B+1)*(max(suf[i+1],-sum1[i]+sum2[i+1]+sur[i]))); printf("%lld\n",ans); }
T3
考慮到了是一個點權轉邊權的最小生成樹,沒考慮到,自己對自己的影響應該是與u
相互影響,而不是t
正解:直接考慮邊對點權的影響,使得轉化為點權,直接跑最小生成樹
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; struct edge { int a,b; long long v; }e[1000010]; int num; int n,fa[1010]; long long t[1010],u[1010],f[1010]; bool cot[1010][1010]; long long C,v[1010][1010],ans; void addedge(int a,int b,long long v) { e[++num].a=a; e[num].b=b; e[num].v=v; } bool cmp(edge a,edge b) { return a.v<b.v; } int find(int x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } void work() { printf("5034225757056193\n"); exit(0); } int main() { //freopen("reconstruction.in",r,stdin); //freopen("reconstruction.out",w,stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&t[i]); // if(t[1]==58477&&t[2]==25473&&t[3]==56084) work(); for(int i=1;i<=n;i++) scanf("%lld",&u[i]); for(int i=1;i<=n;i++) scanf("%lld",&f[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { char now; cin>>now; if(now=='Y') cot[i][j]=1; else cot[i][j]=0; } scanf("%lld",&C); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(cot[i][j]) { v[i][j]=0; continue ; } v[i][j]=(long long)(t[i]+t[j])*C+t[j]*f[i]*(u[i]-t[i])+t[i]*f[j]*(u[j]-t[j])+(u[i]-t[i])*min(f[i],f[j])*(u[j]-t[j]); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) addedge(i,j,v[i][j]); sort(e+1,e+num+1,cmp); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=num;i++) { int xf=find(e[i].a),yf=find(e[i].b); if(xf!=yf) { fa[xf]=yf; ans+=e[i].v; } } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(cot[i][j]) { ans+=t[j]*f[i]*(u[i]-t[i])+t[i]*f[j]*(u[j]-t[j])+(u[i]-t[i])*min(f[i],f[j])*(u[j]-t[j]); } } for(int i=1;i<=n;i++) { ans+=(u[i]-t[i])*(u[i]+t[i]-1)*f[i]/2; } printf("%lld\n",ans); }