6 solutions

  • 3
    @ 2021-12-29 20:30:53

    动态规划

    顺推

    • 推演过程:
      • 13 ====>13
      • 11 8 ====>24 21
      • 12 7 26 ====>36 31 47
      • 6 14 15 8 ====>42 50 62 55
      • 12 7 13 24 11 ====>54 57 75 86 66

    完整代码

    #include<bits/stdc++.h>   
    #define ll long long
    using namespace std;
    ll n,num[1005][1005];
    ll cnt[1005][1005],ans;  
    int main()
    {
        std::ios::sync_with_stdio(false);
        memset(num,0,sizeof(num));//本题使用动态规划
        memset(cnt,0,sizeof(cnt));//顺推
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                cin>>num[i][j];
        cnt[1][1]=num[1][1];
        for(int i=2;i<=n;i++)//状态转化 
            for(int j=1;j<=i;j++)
                cnt[i][j]=num[i][j]+max(cnt[i-1][j-1],cnt[i-1][j]);
    
        for(int i=1;i<=n;i++){//找最大 
            if(ans<cnt[n][i])
                ans=cnt[n][i]; 
        }
        cout<<ans;
        return 0;
    }
    

    逆推

    • 推演过程:
      • 13 ====>86
      • 11 8 ====>57 73
      • 12 7 26 ====>39 46 65
      • 6 14 15 8 ====>18 27 39 32
      • 12 7 13 24 11 ====>12 7 13 24 11
    for(int i=1;i<=n;i++)
        cnt[n][i]=num[n][i];
    for(int i=n-1;i>=1;i--){
        for(int j=1;j<=i;j++)
            cnt[i]][j]=num[i][j]+max(cnt[i-1][j-1],cnt[i-1][j]);
    }
    cout<<cnt[1][1];//cnt[1][1]为最大
    

    在逆推的基础上可以用一维数组进行空间优化

    • 推演过程:
      • 86 73 65 32 11
      • 57 73 65 32 11
      • 39 46 65 32 11
      • 18 27 39 32 11
      • 12 7 13 24 11
    #include<bits/stdc++.h>   
    #define ll long long
    using namespace std;
    ll n,num[1005][1005];
    ll cnt[1005],ans; 
    int main()
    {
        std::ios::sync_with_stdio(false);
        memset(num,0,sizeof(num));
        memset(cnt,0,sizeof(cnt));
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
                cin>>num[i][j];
        for(int i=1;i<=n;i++)//先将最后一组数据赋给cnt
            cnt[i]=num[n][i];
        for(int i=n-1;i>=1;i--)
            for(int j=1;j<=i;j++)
                cnt[j]=num[i][j]+max(cnt[j],cnt[j+1]);
        cout<<cnt[1];
        return 0;
    }
    
    • 2
      @ 2021-12-30 17:16:23

      我支持春哥

      • 1
        @ 2023-8-17 9:53:38

        动态规划,来看我的。

        #include<bits/stdc++.h>
        using namespace std;
        typedef long long LL;
        //dp[i][j]//i:高度,j:位置
        /*
        dp[i][j] = max(dp[i+1][j],dp[i+1][j]) + w[i][j]
        
         */
        const int N = 1e3+10;
        int w[N][N]; //每个点的权值
        LL dp[N][N]; //存储每个点及以下的权值和
        int main(){
        	int R;
        	cin>>R;
        	for(int i=1;i<=R;i++){
        		int j=i;
        		for(int j=1;j<=i;j++){
        			int c;
        			cin>>c;
        			w[i][j] = c;
        		}
        	}
        	for(int i=R;i>=1;i--){
        		for(int j=1;j<=i;j++){
        			if(i==R){
        				dp[i][j]=w[i][j];
        			}
        			else{
        				dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + w[i][j];
        			}
        		}
        	}
        	cout<<dp[1][1]<<endl;
        	return 0;
        }
        
        • 1
          @ 2022-4-1 15:40:39

          我相信不少人,第一反应 肯定是 DFS 吧,所以 在这里 把 DFS 和 DP 的代码 都奉上。当然 单纯的 DFS 是过不了的。会超时!

          #include <iostream>
          #include <algorithm>
          
          using namespace std;
          
          int maxSum = 0;
          int sum = 0;
          int arr[1005][1005];
          bool vis[1005][1005];
          int R;
          
          int off[2][2] = { {1,0},{1,1} };
          int dp[1005][1005];
          
          void dfs11(int x,int y) {
          	if (vis[x][y]) {
          		return;
          	}
          	else {
          		vis[x][y] = true;
          		sum += arr[x][y];
          	}
          	if (x == R) {// 已经走到了 最底部
          		if (maxSum < sum) {
          			maxSum = sum;
          		}
          		return;
          	}
          
          	for (int i = 0; i < 2; ++i) {
          		int tempX = x + off[i][0];
          		int tempY = y + off[i][1];
          		if (tempY > tempX) {
          			continue;
          			
          		}
          		dfs11(tempX, tempY);
          		vis[tempX][tempY] = false;
          		sum -= arr[tempX][tempY];
          	}
          
          }
          
          int main(void) {
          	
          	cin >> R;
          	for (int i = 1; i <= R; ++i) {
          		for (int j = 1; j <= i; ++j) {
          			cin >> arr[i][j];
          		}
          	}
          
          	//dfs11(1, 1);// 从 第一行 第一列 开始 走
          	//dp[i][j] = dp[i-1][j] 
          	for (int i = 1; i <= R; ++i) {
          		for (int j = 1; j <= i; ++j) {
          			if (j == 0) {
          				dp[i][j] = dp[i - 1][j] + arr[i][j];// 只有一种选择
          			}
          			else if (j == i) {
          				dp[i][j] = dp[i - 1][j - 1] + arr[i][j]; // 只有一种选择
          			}
          			else {
          				dp[i][j] = max(dp[i - 1][j - 1], dp[i-1][j]) + arr[i][j];
          			}
          		}
          	}
          
          	for (int i = 1; i <= R; ++i) {
          		maxSum = max(maxSum, dp[R][i]);
          	}
          
          
          	cout << maxSum << endl;
          
          	return 0;
          }
          
          • 0
            @ 2024-2-20 13:02:48

            DFS 记忆化搜索

            #include <bits/stdc++.h>
            using namespace std;
            
            #define DBG(x) cout << #x << "=" << x << endl
            
            const int N = 1005;
            int n, a[N][N], f[N][N];
            
            int dfs(int x, int y) {
              // 查缓存,记忆化
              if (f[x][y] != -1)
                return f[x][y];
              // 边界:最后一行
              if (x == n)
                return f[x][y] = a[x][y];
              // 记忆化搜索
              return f[x][y] = max(dfs(x + 1,y), dfs(x + 1, y + 1)) + a[x][y];
            }
            
            void solve() {
              scanf("%d", &n);
              for(int i = 1; i <= n; i++)
                for(int j = 1; j <= i; j++)
                  scanf("%d", &a[i][j]);
            
              memset(f, -1, sizeof f);
              dfs(1, 1);
              printf("%d\n", f[1][1]);
            }
            
            int main() {
              solve();
            
              return 0;
            }
            
            • 0
              @ 2022-1-2 19:01:09

              emm....雀食是个动态规划的模板题,直接上代码吧

              #include<iostream>
              #include<cstdio>
              #include<cmath>
              #include<cstdlib>
              #include<algorithm>
              #include<cstring>
              
              using namespace std;
              int num[1005][1005];
              int main(void)
              {
              	int n;
              	cin>>n;
              	for(int i=1;i<=n;i++)
              		for(int k=1;k<=i;k++) cin>>num[i][k];//输入
              		
              	for(int i=1;i<=n;i++)
              		for(int k=1;k<=i;k++) num[i][k]=max(num[i][k]+num[i-1][k],num[i][k]+num[i-1][k-1]);//想象成把数层层往下加,一直加到最后一层
              	
              	int ans=0;
              	for(int i=1;i<=n;i++) ans=max(ans,num[n][i]);//比较最后一层哪个最大输出即可
              	
              	cout<<ans; 
              	
              	
              	return 0;
              }
              
              • 1

              Information

              ID
              87
              Time
              1000ms
              Memory
              256MiB
              Difficulty
              4
              Tags
              # Submissions
              189
              Accepted
              81
              Uploaded By