中山普及Day13——普及
又是迷之自信的说。。。估的230,考的50整,我欲上天呐!!!
T1:深渊(怕不是黑暗种族聚集地???)
思路:动归。而且是简单动归。转移方程:Fi,j=max(Fi-1,j,Fi,j,Fi-1,(j-modi+m)%m)其中i表示第i个,j表示此时的余数。
最后答案即为Fi,0。
见代码:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int n,m,v[5001],mod[5001],dp[5001][5001]; int main() { freopen("abyss.in","r",stdin); freopen("abyss.out","w",stdout); memset(dp,-0x3f3f3f,sizeof(dp)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&v[i]); mod[i]=v[i]%m; } dp[0][0]=0; for(int i=1;i<=n;i++) for(int j=0;j<m;j++) { dp[i][j]=max(dp[i-1][j],dp[i][j]); dp[i][j]=max(dp[i][j],dp[i-1][(j-mod[i]+m)%m]+v[i]); } printf("%d",dp[n][0]); return 0; }
好题哉!!!
T2:fight
有一只触手怪,有好多好多触手。(莫不是从诡秘之主里跑出来的)
类似这种:
每条触手上有n条绳子,那是勇士为了杀死他完成工会任务套上的。但是触手怪有一些灵智,所以每两根触手只能绑一根。现给你一种绑法,看是否可行。
思路:贪心,每次从大到小排序,把最大的向下绑好。最后看会不会多出来就可以了。
见代码:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int t,n,a[801]; bool flag; bool cmp(int x,int y) { return x>y; } int main() { freopen("fight.in","r",stdin); freopen("fight.out","w",stdout); scanf("%d",&t); for(int k=1;k<=t;k++) { flag=false; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { int k=0; for(int j=1;i+j<=n;j++) { if(a[i+j]>0) { a[i+j]--; k++; } if(k==a[i]) { break; } } if(k!=a[i]) { flag=true; break; } sort(a+1,a+1+n,cmp); } if(flag==true) printf("NO\n"); else printf("YES\n"); } return 0; }
好题哉!!!
T3:游戏机
思路:拿一个前向星存个图,然后储蓄一下左上到右下,左下到右上的路径长度,即为0或1,因为不可能再走一遍,会诞生环。
然后安心跑最短路,迪杰就可以了,可怜我不会前向星,全部爆空间。
见代码;
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int n,m,flag=1,g[20001][20001],dij[20001]; bool book[20001]; char c; void dijs() { dij[1]=0; book[1]=true; while(flag!=n*m) { int minIndex=0x3f3f3f3f,minnum=1; for(int i=2;i<=n*m;i++) { if(!book[i]) { if(minIndex>dij[i]) { minIndex=dij[i]; minnum=i; } } } book[minnum]=true; flag++; for(int i=2;i<=n*m;i++) { if(!book[i]&&g[minnum][i]!=0x3f3f3f) { if(g[minnum][i]+dij[minnum]<dij[i]) dij[i]=g[minnum][i]+dij[minnum]; } } } } int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); memset(g,0x3f3f3f,sizeof(g)); memset(dij,0x3f3f3f,sizeof(dij)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) g[i][i]=0; for(int i=1;i<n;i++) for(int j=1;j<m;j++) { scanf(" %c",&c); if(int(c)==92) { g[(i-1)*m+j+1][i*m+j]=1;g[i*m+j][(i-1)*m+j+1]=1; g[(i-1)*m+j][i*m+j+1]=0;g[i*m+j+1][(i-1)*m+j]=0; if(((i-1)*m+j+1)==2&&(i*m+j)==(i*m+1)) { dij[m+2]=0; } } else { g[(i-1)*m+j][i*m+j+1]=1;g[i*m+j+1][(i-1)*m+j]=1; g[(i-1)*m+j+1][i*m+j]=0;g[i*m+j][(i-1)*m+j+1]=0; if((i-1)*m+j==1&&i*m+j+1==i*m+2) { dij[m+2]=1; } } } dijs(); printf("%d",dij[n*m]); return 0; }
好题哉!!!
T4:拓扑排序
如题,再嵌一个中位数。这个非常复杂,这里不讲。
好题哉!!!