题解:dp+dfs.
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 40; int dp[maxn][maxn]; int cnt[maxn][maxn]; int n; int dfs(int x,int y) { if(x==1&&y==1) return cnt[1][1]; if(y==1) return dfs(x-1,y)+cnt[x][y]; if(x>1)return max(dfs(x-1,y),dfs(x-1,y-1))+cnt[x][y]; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { scanf("%d",&cnt[i][j]); } } int x,y; scanf("%d %d",&x,&y); for(int i=1;i<=n;i++) dp[n][i] = cnt[n][i]; for(int i=n-1;i>=x;i--) { for(int j=1;j<=i;j++) { dp[i][j] = max(dp[i+1][j],dp[i+1][j+1])+cnt[i][j]; } } int sum = 0; sum = dfs(x,y); sum = sum+dp[x][y]-cnt[x][y]; printf("%d ",sum); return 0; } /* 4 7 1 2 3 4 5 7 3 8 9 3 2 */
题解:dfs.咦,我本来是来炼dp的。。。不做水题了。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; int n,m; const int maxn = 105; int cnt[maxn][maxn]; int vis[maxn][maxn]; int dp[maxn][maxn]; int dfs(int x,int y) { if(x<1||y<1) return 0; if(x>n||y>m) return 0; if(vis[x][y]) return dp[x][y]; vis[x][y] = 1; int a,b,c,d; a = b = c = d = 0; if(cnt[x-1][y]<cnt[x][y]) a = dfs(x-1,y); if(cnt[x+1][y]<cnt[x][y]) b = dfs(x+1,y); if(cnt[x][y+1]<cnt[x][y]) c = dfs(x,y+1); if(cnt[x][y-1]<cnt[x][y]) d = dfs(x,y-1); dp[x][y] = max(max(a,b),max(c,d))+1; return dp[x][y]; } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&cnt[i][j]); } } int maxx = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { maxx = max(dfs(i,j),maxx); } } printf("%d ",maxx); }
题解:接触的第一道区间dp题。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 111; char s[maxn]; int dp[maxn][maxn]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%s",s+1); int n = strlen(s+1); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i == j) dp[i][j] = 1; else dp[i][j] = 1000; } dp[i][i-1] = 0; } //i和j分别表示一段连续字符的起点和终点 for(int l=1;l<=n-1;l++) { for(int i=1;i+l<=n;i++) { int j = i+l; 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 ",dp[1][n]); } } /* 31 ()([)][]) */