• codefores刷题心得3 思维+dp(特别好玩)


    1.1438 C. Engineer Artem(思维)

    我当时不会看的题解,很自闭,没想到今天看dalao,他也没想到,hhhhhh

    题目链接https://codeforces.com/contest/1438/problem/C

    题目大意:给你一个数字矩阵,你可以选择任意位置+1操作(最多加一次),让你左右相邻和上下相邻的数字都不相同。

    解题思路

    这题上下左右不可以相同,但是斜着的都是可以相同的。就可以把矩阵分成两块,只需要保证一块为奇数,另一块为偶数即可。就一定不会相同的。

    这道题的题解太巧了呀!!!我什么时候能有这样的好脑子

    AC代码

    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e2+4;
    int mp[maxn][maxn];
    
    int main(){
    	int t;
    	cin>>t;
    	int n,m;
    	while(t--){
    		scanf("%d%d",&n,&m);
    		for(int i=0;i<n;i++){
    			for(int j=0;j<m;j++){
    				cin>>mp[i][j];
    				if((i+j)%2==0){
    					if(mp[i][j]%2!=0){
    						mp[i][j]++;
    					}	
    				}else{
    					if(mp[i][j]%2==0){
    						mp[i][j]++;
    					}
    				}
    			}
    		}
    		for(int i=0;i<n;i++){
    			for(int j=0;j<m;j++)
    				cout<<mp[i][j]<<' ';
    			cout<<endl;
    		}
    	
    	}	
    	return 0;
    }
    

    2.1389 B. Array Walk

    dalao眼中的简单dp

    题目链接:https://codeforces.com/contest/1389/problem/B

    题目大意:从第一个位置进行移动,每次可向左或者向右移动,数组大小为n,移动次数为k,最多向左移动次数为z,让你求移动得到的最大的加和。

    样例解释:

    第一个只能向右移动: 1+5+4+3+2=15

    第二个能向左移动一次: 1 +5+4+5+3=19

    .....

    所以可以使用dp操作,因为z<=5所以最多一次操作有5个可能的位置。

    dp[i][j] //i代表第几次操作,j代表当前在哪个位置 
        
    dp[1][2]=a[1]+a[2]//经过一次操作,不可能在1的位置
    
    dp[2][3]=dp[1][2]+a[3]
    dp[2][1]=dp[1][2]+a[1]
    
    dp[3][4]=dp[2][3]+a[4]
    dp[3][2]=dp[2][3]+a[2]
    
    dp[4][5]=dp[3][4]+a[5]
    dp[4][3]=dp[3][2]+a[3],dp[3][4]+a[3]
    dp[4][1]=dp[3][2]+a[1]
    
    dp[5][6]=dp[4][5]+a[6]
    dp[5][4]=dp[4][3]+a[4],dp[4][5]+a[4]
    dp[5][2]=dp[4][3]+a[2],dp[4][1]+a[2]
    

    但是n是1e5的数据大小,不能开这么大,可以开到dp maxn 10,10代表的是左移的次数,一次左移,两个位置,因为只能是左移和右移,所以岔开的是两个位数。5次两个位数,第i次操作就是i,i - 2,

    i - 4 , i - 6,i - 8

    #include <iostream>
    using namespace std;
    const int maxn = 1e5+5;
    int a[maxn];
    int dp[maxn][10];//第二个是当前向左移动的次数 
    int main(){
    	int t,n,k,z;
    	cin>>t;
    	while(t--){
    		cin>>n>>k>>z;
    		for(int i=1;i<=n;i++) cin>>a[i];
    		for(int i=1;i<=k+1;i++){ 
    			for(int j=0;j<=z;j++){
    				if(j==0) dp[i][0]=dp[i-1][0]+a[i];
    				else{//一个j代表两个位置。 
    					dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]);
    					dp[i][j]+=a[i-j*2];
    				}
    			}
    		} 
    		int ans=0;
    		for(int i=0;i<=z;i++){
    			ans=max(ans,dp[k+1][i]);
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

    qqz qwq

  • 相关阅读:
    Flasback数据库(闪回数据库)
    Oracle回收站
    PL/SQL中如何执行DDL、SCL?
    oracle中的隐式提交(auto commit)
    raise_application_error用法
    sqlplus中"-S"和"-L"用法
    愿随君,走天涯
    你的过去,我不曾参与;你的未来,与你紧相依
    Oracle中SAVEPOINT和ROLLBACK用法
    Linux基础命令-Nginx-正则表达式( grep sed awk )-Shell Script--etc
  • 原文地址:https://www.cnblogs.com/AC673523745/p/14023325.html
Copyright © 2020-2023  润新知