1. 程式人生 > >LeetCode 568. Maximum Vacation Days

LeetCode 568. Maximum Vacation Days

題意:有N個city可以travel,每個星期可以選擇換一個city(或者停留在當前city),city之間可能連通也可能不連通。每個city可以travel的時間不同且每個星期不一樣。一共K個星期,求最多可以travel的總天數。

這一題看起來就很像DP,狀態轉移是從這周到下週,一個city到下一個city,因為轉移時需要判斷city是否連通,所以定義狀態dp[i,j]為第j個星期時travel第i個city,前j周的總的travel天數。

開始沒留意到同一個city可以重複訪問,如果要避免visit相同的city就要考慮之前所有的decision,所以不能只用狀態代替decision sequence。o(╯□╰)o 感覺這種case只能用dfs。

狀態轉移是列舉下一個可以訪問的city,dp[k,j+1]=max(dp[k,j+1],dp[i,j]+day[k,j+1) where k=i or k is connected to i。

注意要避免不可以到達某個city的case,所以dp[i,j]初始值是-1,如果狀態轉移中的dp[i,j]是-1,則直接skip。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
#include<stack>
using namespace std;

//leetcode 568. Maximum Vacation Days
int T;
int N;
int M;
int K;
class Solution {
public:
    int maxVacationDays(vector<vector<int>>& flights, vector<vector<int>>& days) {
        int N=flights.size();
        int K=days[0].size();
        int** dp=new int*[N];
        for(int i=0;i<N;i++)
        {
            dp[i]=new int[K];
        }
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<K;j++)
            {
                dp[i][j]=-1;
                //cout<<dp[i][j]<<endl;
            }
        }
        dp[0][0]=days[0][0];
        for(int i=1;i<N;i++)
        {
            if(flights[0][i]==1)
            {
                dp[i][0]=days[i][0];
            }
//            else
//            {
//                dp[i][0]=-1;//no reachable
//            }
        }

        for(int j=0;j<K-1;j++)
        {
            for(int i=0;i<N;i++)
            {
                if(dp[i][j]==-1)
                {
                    continue;
                }
                for(int k=0;k<N;k++)
                {
                    if(flights[i][k]==0&&i!=k)//can stay in one city for consecutive weeks
                    {
                        continue;
                    }
                    else
                    {
                        dp[k][j+1]=max(dp[k][j+1],dp[i][j]+days[k][j+1]);
                    }
                }
            }
        }
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<K;j++)
            {
                cout<<dp[i][j]<<" ";
            }
            cout<<endl;
        }

        int ret=0;
        for(int i=0;i<N;i++)
        {
            ret=max(ret,dp[i][K-1]);
        }
        for(int i=0;i<N;i++)
        {
            delete[] dp[i];
        }
        delete[] dp;
        return ret;
    }
};
int main()
{
    freopen("input.txt","r",stdin);
    cin>>T;
    for(int ca=1;ca<=T;ca++)
    {
        cin>>N>>K;
        vector<vector<int>>flights;
        vector<vector<int>>days;
        for(int i=0;i<N;i++)
        {
            flights.push_back(vector<int>());
            for(int j=0;j<N;j++)
            {
                int tmp;
                cin>>tmp;
                flights[i].push_back(tmp);
            }
        }
        for(int i=0;i<N;i++)
        {
            days.push_back(vector<int>());
            for(int j=0;j<K;j++)
            {
                int tmp;
                cin>>tmp;
                days[i].push_back(tmp);
            }
        }
        Solution sol;
        cout<<"Case #"<<ca<<": "<<sol.maxVacationDays(flights,days)<<endl;;
    }
    return 0;
}