3 solutions

  • 2
    @ 2024-4-9 19:58:12

    有彩蛋

    题意

    从西北角走到东南角

    只能往东走或南走

    沿途最多能收取到多少花生

    思路

    拿这个样例

    3 3
    1 1 5
    3 4 6
    2 1 3
    

    我们能知道r=3,c=3r=3,c=3

    花生地是

    a[3][3]

    1 1 5
    3 4 6
    2 1 3
    

    我们先将i=0j=0i=0 或 j=0的地先都分别加上北面或西面的花生数目(因为这两条道没有别的选择)

    再从11开始遍历,每个值为a[i][j]+max(a[i1][j],a[i][j1])a[i][j]+max(a[i-1][j],a[i][j-1])

    因为要取北面或西面的最多花生

    输出东南角的花生数目

    代码

    #include<iostream>
    #include<queue>
    using namespace std;
    int main()
    {
        int t;
        cin>>t;//输入
        while(t--)
        {
        	int r,c;
        	int a[114][114];
        	cin>>r>>c;//输入
        	for(int i=0;i<r;i++)
        	{
        		for(int j=0;j<c;j++)
        		{
        			cin>>a[i][j];//输入
        			if(j==0 && i>0)a[i][j]+=a[i-1][j];//选择北面的
        			if(i==0 && j>0)a[i][j]+=a[i][j-1];//选择西面的
    			}
    		}
    		for(int i=1;i<r;i++)//从1开始
    		{
    			for(int j=1;j<c;j++)//从1开始
    			{
    				a[i][j]+=max(a[i-1][j],a[i][j-1]);//取北面和西面的最大值
    			}
    		}
    		cout<<a[r-1][c-1]<<endl;//输出最底的
    	}
        return 0;//完结散花
    }
    

    彩蛋

    这是我第一道没有任何人帮助的AC的DP题

    点赞就祝你身体健康

    • @ 2024-4-9 20:38:00

      typo第一行:应该是从西北走到东南

    • @ 2024-4-10 9:21:40

      雀食,改了@

  • 0
    @ 2024-4-12 13:49:44
    注意!!!

    因为是从北走到南,所以要倒着dp

    #include<bits/stdc++.h>
    using namespace std;
    int arr[110][110],f[110][110];
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n,m;
            cin>>n>>m;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++) cin>>arr[i][j];
            }
            memset(f,0,sizeof(f));
            arr[0][0]=0;
            for(int i=n;i>=0;i--){
                for(int j=m;j>=0;j--){
                    f[i][j]=max(f[i+1][j],f[i][j+1])+arr[i][j];
                }
            }
            int maxx=-1;
            for(int i=1;i<=n;i++){
                for(int j=0;j<=n;j++)maxx=max(maxx,f[i][j]);
            }
            cout<<maxx<<'\n';
        }
        return 0;
    }
    
  • 0
    @ 2024-3-9 17:05:13

    A1284 摘花生

    题意

    见题目

    底层逻辑

    最短路径问题但是改版 具体表现为dp[j][k]=min(dp[j-1][k],dp[j][k-1])+c[j][k] (c为矩阵) 极端情况(如处于上边缘或侧边缘)需要单独考虑,具体见歹马19-27行

    歹马

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int t;
    	cin>>t;
    	for(int i=0;i<t;i++){
    		int a,b;
    		cin>>a>>b;
    		int c[a][b];
    		int dp[a][b];
    		memset(dp,0,sizeof(dp));
    		for(int j=0;j<a;j++){
    			for(int k=0;k<b;k++){
    				cin>>c[j][k];
    			}
    		}
    		for(int j=0;j<a;j++){
    			for(int k=0;k<b;k++){
    				if(j==0&&k==0){
    					dp[j][k]=c[j][k];
    				}
    				else if(j==0&&k!=0){
    					dp[j][k]=dp[j][k-1]+c[j][k];
    				}
    				else if(j!=0&&k==0){
    					dp[j][k]=dp[j-1][k]+c[j][k];
    				}
    				else{
    					dp[j][k]=max(dp[j-1][k],dp[j][k-1])+c[j][k];
    				}
    			}
    		}
    		cout<<dp[a-1][b-1]<<endl;
    	}
    	return 0;
    }
    
    
    • @ 2024-3-9 22:46:11

      记得点赞!

    • @ 2024-3-16 15:33:20

      更正一下,表达式为dp[j][k]=max(dp[j-1][k],dp[j][k-1])+c[j][k]

  • 1

Information

ID
769
Time
1000ms
Memory
256MiB
Difficulty
5
Tags
# Submissions
35
Accepted
15
Uploaded By