H题:记忆化dp
dp[i][j]记录i,j这个位置的状态是0,1,表示第一个人遇到此状态的胜败。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define maxn 1111 int row[maxn][maxn],col[maxn][maxn]; int dp[maxn][maxn];//表示改点是否是必胜态 int main() { int n,x; while(scanf("%d",&n)!=EOF) { memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&x); row[i][j]=(row[i][j-1]+x)%2; col[i][j]=(col[i-1][j]+x)%2; } } memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(dp[i-1][j]==0&&row[i][j]==0) dp[i][j]=1; if(dp[i][j-1]==0&&col[i][j]==0) dp[i][j]=1; } } if(dp[n][n]) { printf("W\n"); } else { printf("L\n"); } } return 0; }G题:模拟lca的思想。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define eps 1e-10 using namespace std; int mp[1111][1111],dp[1111][1111]; int main() { // freopen("C:\\Users\\cugbacm\\Desktop\\in.in","r",stdin); // freopen("C:\\Users\\cugbacm\\Desktop\\out1.txt","w",stdout); int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { scanf("%d",&mp[i][j]); mp[j][i]=mp[i][j]; } } int ans=mp[1][2]-1; for(int i=3;i<=n;i++) { int tmp=mp[i][1]; for(int j=2;j<i;j++) { int t=mp[i][1]-(mp[i][1]+mp[j][1]-mp[i][j])/2; if(t<tmp) tmp=t; } ans+=tmp-1; } printf("%d\n",ans); } return 0; }F题:图上的dp,枚举每个方向可能取的步数,取最小值。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define maxn 1055 #define INF 0x7fffffff #define ll long long using namespace std; char s[maxn]; ll dp[10][4][maxn][maxn]; int mp[maxn][maxn]; int main() { int r,c; while(scanf("%d%d",&r,&c)!=EOF) { int maxc=0,minc=9; for(int i=1;i<=r;i++) { scanf("%s",s); int l=strlen(s); for(int j=0;j<l;j++) { mp[i][j+1]=s[j]-'0'; maxc=max(maxc,mp[i][j+1]); minc=min(minc,mp[i][j+1]); } } ll ans=0; // memset(dp,0,sizeof(dp)); for(int k=minc;k<=maxc;k++) { for(int i=1;i<=r;i++) { //左上 for(int j=1;j<=c;j++) { dp[k][0][i][j]=INF; if(i>1&&mp[i-1][j]==k) dp[k][0][i][j]=2; if(j>1&&mp[i][j-1]==k) dp[k][0][i][j]=2; if(i>1) { dp[k][0][i][j]=min(dp[k][0][i][j],dp[k][0][i-1][j]+2); } if(j>1) { dp[k][0][i][j]=min(dp[k][0][i][j],dp[k][0][i][j-1]+2); } } //右上 for(int j=c;j>=1;j--) { dp[k][1][i][j]=INF; if(i>1&&mp[i-1][j]==k) dp[k][1][i][j]=2; if(j<c&&mp[i][j+1]==k) dp[k][1][i][j]=2; if(i>1) { dp[k][1][i][j]=min(dp[k][1][i][j],dp[k][1][i-1][j]+2); } if(j<c) { dp[k][1][i][j]=min(dp[k][1][i][j],dp[k][1][i][j+1]+2); } } } for(int i=r;i>=1;i--) { //左下 for(int j=1;j<=c;j++) { dp[k][2][i][j]=INF; if(j>1&&mp[i][j-1]==k) dp[k][2][i][j]=2; if(i<r&&mp[i+1][j]==k) dp[k][2][i][j]=2; if(j>1) { dp[k][2][i][j]=min(dp[k][2][i][j],dp[k][2][i][j-1]+2); } if(i<r) { dp[k][2][i][j]=min(dp[k][2][i][j],dp[k][2][i+1][j]+2); } } //右下 for(int j=c;j>=1;j--) { dp[k][3][i][j]=INF; if(i<r&&mp[i+1][j]==k) { dp[k][3][i][j]=2; } if(j<c&&mp[i][j+1]==k) { dp[k][3][i][j]=2; } if(i<r) { dp[k][3][i][j]=min(dp[k][3][i][j],dp[k][3][i+1][j]+2); } if(j<c) { dp[k][3][i][j]=min(dp[k][3][i][j],dp[k][3][i][j+1]+2); } } } for(int i=1;i<=r;i++) { for(int j=1;j<=c;j++) { ll min_x=INF; for(int l=0;l<4;l++) { min_x=min(min_x,dp[k][l][i][j]); } if(min_x!=INF) ans+=min_x; } } } printf("%lld\n",ans); } return 0; }