zoukankan      html  css  js  c++  java
  • HDU 5623 KK's Number (博弈DP)

    KK's Number

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/121332#problem/K

    Description

    Our lovely KK has a funny mathematical game:This game requires two people,There are numbers,every time KK will take the numbers,first.Every time you can take any number of the numbers.Until the number is taken.The minimum number of numbers is the score for each time.KK and the opponent's strategy is as much as possible to make their score minus the opponent's score more.In this case,How much is the final KK score minus the opponent's score?

    Input

    The first line of the input file contains an integer , which indicates the number of test cases.
    For each test case, there are two lines,in the first line is a integer ,the other line has positive integers(no more than ).

    Output

    For each test case, there are one lines,includes a integer,indicating the final KK's score minus the opponent's score.

    Sample Input

    1
    3
    1 3 1

    Sample Output

    2

    Hint

    Firstly KK take 3;and the opponent take 1,1,so the result is 2.

    题意:

    给出N个数字,A和B两个人先后从中任取任意个数;
    每次操作的权值为取出数中的最小数;
    两人轮流取,直到N个数字取完;
    两人均为最策略,要最大化权值差(自身-对方);

    题解:

    博弈DP:
    先将数字升序排列:
    dp[i]表示对于前i个数字能够得到的最大权值差(先手值-后手值);
    转移方程为:
    dp[i] = max(dp[i-1], num[i]-dp[i-1]);
    解释:
    对于当前的i,可以取1~i中的任意一个作为当前操作的权值;(因为取了某个数后,肯定会一并把比它大的数一起取掉);
    dp[j-1]为取了当前num[j]后,对手在上一次所取到的最优值.
    for(int j=1; j<=i; j++) {
    dp[i] = max(dp[i], num[j] - dp[j-1]);
    }
    如果是上述n*n的dp过程,肯定会超时;
    考虑一下,其实dp[i-1]覆盖了除了num[i]-dp[i-1]的其他所有情况.
    所以只需要一维dp即可.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #define LL long long
    #define eps 1e-8
    #define maxn 55000
    #define inf 0x3f3f3f3f
    #define IN freopen("in.txt","r",stdin);
    using namespace std;
    
    int n;
    int num[maxn];
    int dp[maxn];
    
    int main(int argc, char const *argv[])
    {
        //IN;
    
        int t; cin >> t;
        while(t--)
        {
            cin >> n;
            for(int i=1; i<=n; i++) scanf("%d", &num[i]);
            sort(num+1, num+1+n);
    
            memset(dp, 0, sizeof(dp));
            for(int i=1; i<=n; i++) {
    //            for(int j=1; j<=i; j++) {
    //                dp[i] = max(dp[i], num[j] - dp[j-1]);
    //            }
                dp[i] = max(dp[i-1], num[i] - dp[i-1]);
            }
    
            printf("%d
    ", dp[n]);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    TOMCAT清理
    tomcat 热部署、热加载 精析
    TOMCAT配置数据库连接池
    TOMCAT修改端口号
    TOMCAT配置管理员
    Go语言net/http 解读.
    《coredump问题原理探究》Linux x86版7.7节 set对象
    Asp.net与office web apps的整合
    【设计模式】代理模式实现连接池
    手把手实现Java权限(1)-Shiro介绍
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5697604.html
Copyright © 2011-2022 走看看