题意:有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;
}