挑战程序竞赛系列(48):4.2 推理与动态规划算法(1)

综合技术 2017-09-05 阅读原文

挑战程序竞赛系列(48):4.2 推理与动态规划算法(1)

详细代码可以fork下Github上 leetcode 项目,不定期更新。

练习题如下:

POJ 1082: Calendar Game

思路:

可以由2001年11月4号推出1,2,3号的输赢态,因为1,2,3没有任何选择,只能+1,那么10月份该如何?

对于10月份有两种情况,选择同月+1和下个月同天,它的策略就是找下一状态的必输态,找到任何一种必输态,对于当前状态就必赢。

所以递推式为:

dp[year][month][day]: 表示在某天的输赢态

dp[year][month][day] = {选择同月下一天} || {选择下月同一天}

注意一些边界条件,比如一年的最后一天,一个月的最后一天,以及闰年,大小月等。

代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main{

    String INPUT = "./data/judge/201709/P1082.txt";

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    static int[] leap_month    = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static int[] nonleap_month = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    boolean[][][] dp = new boolean[200][13][32];

    void solve() {
        int T = ni();

        DP();
        while (T --> 0) {
            int year  = ni();
            int month = ni();
            int day   = ni();
            out.println(dp[year - 1900][month][day] ? "YES" : "NO");
        }
    }

    void DP() {
        dp[2001 - 1900][11][3] = true;
        dp[2001 - 1900][11][2] = false;
        dp[2001 - 1900][11][1] = true;
        for (int j = 4; j = 1; --mon) {
            for (int j = nonleap_month[mon]; j >= 1; --j) {
                // 当前月是否为最后一天
                if (j == nonleap_month[mon]) {
                    dp[101][mon][j] |= !dp[101][mon + 1][1];
                }
                else {
                    dp[101][mon][j] |= !dp[101][mon][j + 1];
                }

                if (j = 0; --year) {
            int[] month = leap(year) ? leap_month : nonleap_month;
            for (int mon = 12; mon >= 1; --mon) {
                for (int day = month[mon]; day >= 1; --day) {
                    if (mon == 12 && day == month[mon]) { // 1 年中的最后一天
                        dp[year][mon][day] = !dp[year + 1][1][1] || !dp[year + 1][1][day];
                    }
                    else if (day == month[mon]) { // 1个月中的最后一天
                        dp[year][mon][day] |= !dp[year][mon + 1][1];
                        if (day <= 0="" 4="=" 12="" 100="" 400="=" month[mon="" +="" 1])="" {="" dp[year][mon][day]="" |="!dp[year][mon" 1][day];="" }="" else="" 其他="" 1];="" if="" (day="" <="month[mon" %="" boolean="" leap(int="" year){="" return="" (year="" &&="" year="" !="0" ||="" 0);="" fastscanner="" in;="" printwriter="" out;="" void="" run()="" throws="" ioexception="" oj;="" try="" oj="!" system.getproperty("user.dir").equals("f:\java_workspace\leetcode");="" catch="" (exception="" e)="" inputstream="" is="oj" ?="" system.in="" :="" new="" fileinputstream(new="" file(input));="" in="new" fastscanner(is);="" out="new" printwriter(system.out);="" long="" s="System.currentTimeMillis();" solve();="" out.flush();="" (!oj){="" system.out.println("["="" (system.currenttimemillis()="" -="" s)="" "ms]");="" public="" more(){="" in.hasnext();="" int="" ni(){="" in.nextint();="" nl(){="" in.nextlong();="" double="" nd(){="" in.nextdouble();="" string="" ns(){="" in.nextstring();="" char="" nc(){="" in.nextchar();="" class="" bufferedreader="" br;="" stringtokenizer="" st;="" hasnext;="" fastscanner(inputstream="" is)="" br="new" bufferedreader(new="" inputstreamreader(is));="" hasnext="true;" nexttoken()="" while="" (st="=" null="" !st.hasmoretokens())="" st="new" stringtokenizer(br.readline());="" "##";="" st.nexttoken();="" next="null;" hasnext(){="" nextint()="" (next="=" null){="" hasnext();="" more="next;" integer.parseint(more);="" nextlong()="" long.parselong(more);="" nextdouble()="" double.parsedouble(more);="" nextstring(){="" more;="" nextchar(){="" more.charat(0);="" } 
 

CSDN博客

责编内容by:CSDN博客阅读原文】。感谢您的支持!

您可能感兴趣的

LeetCode子域名访问计数-Python3.7 上一篇:LeetCode 键盘行 题目: https://leetcode-cn.com/problems/subdomain-visi...
LeetCode 027. Remove Element(移除元素) 题目描述 英文 Given an array nums and a value val, remove all instances of that va...
LeetCode 665. Non-decreasing Array Non-decreasing Array 题目描述: Given an array with n integers, your task is ...
Leetcode打卡 | No.012 整数转罗马数字 No.12 整数转罗马数字 原题: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 ...
Leetcode: Path Sum IV Path Sum IV Similar Problems: Path Sum III ...