• 2020 计蒜之道 预赛 第三场 石子游戏(简单)(暴力DP)


    石子游戏(简单)

    原题链接

    思路:
    通过形式容易看出是一道DP。其中异或和的情况只有64种,所以我们可以开一维来记录当前异或和的状态。
    在[l,r]利用dp[当前位置][异或和][是否选择当前]来进行状态转移。时间复杂度为O(qnm)。

    比赛时这道题卡了好久,思路很清晰,但就是跑不出正确结果。后来发现原来忽略了f为-1的情况,初始化默认为0了。。

    题解:

    #include<bits/stdc++.h>
    #define MAX 1005
    #define MOD 4294967296
    using namespace std;
    typedef long long ll;
    
    int a[MAX],v[MAX];
    int x[2005];
    int dp[MAX][66][2];
    int f[2005][66];
    
    int main()
    {
    	int t,n,m,q,l,r,i,j,k;
    	scanf("%d%d%d",&n,&m,&q);
    	for(i=0;i<n;i++){
    		scanf("%d%d",&a[i],&v[i]);
    	}
    	for(i=1;i<=q;i++){
    		scanf("%d%d%d",&l,&r,&x[i]);
    		memset(dp,-1,sizeof(dp));
    		dp[l][0][0]=0;
    		dp[l][a[l]][1]=v[l];
    		for(j=l+1;j<=r;j++){
    			for(k=0;k<64;k++){
    				dp[j][k][0]=max(dp[j-1][k][0],dp[j-1][k][1]);
    				dp[j][k][1]=max(dp[j-1][k^a[j]][0],dp[j-1][k^a[j]][1]);
    				if(dp[j][k][1]>-1) dp[j][k][1]+=v[j];  //-1一定要处理
    			}
    		}
    		for(k=0;k<64;k++){
    			f[i][k]=max(dp[r][k][0],dp[r][k][1]);
    		}
    	}
    	
    //	for(i=1;i<=q;i++){
    //		for(j=0;j<64;j++){
    //			printf("%d ",f[i][j]);
    //		}
    //		printf("
    ");
    //	}
    	
    	ll ans=0;
    	for(k=1;k<=q;k++){
    		ll sum=0;
    		for(j=0;j<=m-1;j++){
    			sum+=f[k][j]*(x[k]^j)%MOD;
    			sum%=MOD;
    		}
    		ans+=(k^sum)%MOD;
    		ans%=MOD;
    	}	
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    C和指针学习笔记--第五章
    C和指针学习笔记--第四章
    C和指针学习笔记--第三章
    ipables常用命令
    linux网络设计与实现-----第一章
    iptables
    cJSON学习
    Makefile-更新函数库文件
    Makefile隐晦规则
    【Spark学习笔记】01-Spark简介
  • 原文地址:https://www.cnblogs.com/yzm10/p/13705241.html
Copyright © 2020-2023  润新知