返回顶部

Educational Codeforces Round 95 (Rated for Div. 2) C. Mortal Kombat Tower (DP)

  • 题意:你和基友两人从左往右轮流打怪兽,强怪用\(1\)表示,垃圾用\(0\)表示,但基友比较弱,打不过强怪,碰到强怪需要用一次魔法,而你很强,无论什么怪都能乱杀,基友先打,每人每次至少杀一个怪兽,最多杀两个怪兽,问最少需要用多少次魔法能将怪兽全部打完.

  • 题解:由于在打怪的过程中,每个状态都与之前息息相关,所以我们可以用dp来写,\(dp[i][who]\),\(i\)表示第\(i\)个怪兽,\(who\)表示我或基友,因为基友先打,所以基友的前两个状态我们是确定的,即:\(dp[1][0]=a[1]\),\(dp[2][0]=a[1]+a[2]\),而我在第二个怪兽的状态也是确定的\(dp[2][1]=a[1]\),我们从第三个怪兽开始转移,每次我和基友都可以选择杀一个或两个怪兽,所以就会由两个状态转移过来,因为我是无敌的,所以我的状态就是\(dp[i][1]=min(dp[i-1][0],dp[i-2][0])\),基友的是\(dp[i][0]=min(dp[i-1][1]+a[i],dp[i-2][1]+a[i-1]+a[i])\).然后\(dp[n][0]\)\(dp[n][1]\)取个最小即可.

  • 代码:

    int t;
    int n;
    int a[N];
    int dp[N][2];
    
    int main() {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	t=read();
    	while(t--){
    		n=read();
    		for(int i=1;i<=n;++i){
    			a[i]=read();
    			dp[i][0]=INF;
    			dp[i][1]=INF;
    		}
    		dp[1][0]=a[1];
    		dp[2][0]=a[1]+a[2];
    		dp[2][1]=a[1];
    		for(int i=3;i<=n;++i){
    			dp[i][1]=min(dp[i-1][0],dp[i-2][0]);
    			dp[i][0]=min(dp[i-1][1]+a[i],dp[i-2][1]+a[i-1]+a[i]);
    		}
    		printf("%d\n",min(dp[n][0],dp[n][1]));
    	}
    
        return 0;
    }
    
posted @ 2020-09-15 19:44  _Kolibri  阅读(221)  评论(0)    收藏  举报