最新文章
这里会显示最新的几篇文章摘要。
记录生活,分享知识,与你一起成长。
这里会显示最新的几篇文章摘要。
NOIP2010 提高组 T2
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
乌龟棋的棋盘是一行 \(N\) 个格子,每个格子上一个分数(非负整数)。棋盘第 \(1\) 格是唯一的起点,第 \(N\) 格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中 \(M\) 张爬行卡片,分成 \(4\) 种不同的类型(\(M\) 张卡片中不一定包含所有 \(4\) 种类型的卡片,见样例),每种类型的卡片上分别标有 \(1,2,3,4\) 四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。
游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?
每行中两个数之间用一个空格隔开。
第 \(1\) 行 \(2\) 个正整数 \(N,M\),分别表示棋盘格子数和爬行卡片数。
第 \(2\) 行 \(N\) 个非负整数,\(a_1,a_2,…,a_N\),其中 \(a_i\) 表示棋盘第 \(i\) 个格子上的分数。
第 \(3\) 行 \(M\) 个整数,\(b_1,b_2,…,b_M\),表示 \(M\) 张爬行卡片上的数字。
输入数据保证到达终点时刚好用光 \(M\) 张爬行卡片。
一个整数,表示小明最多能得到的分数。
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
73
每个测试点 1s。
小明使用爬行卡片顺序为 \(1,1,3,1,2\),得到的分数为 \(6+10+14+8+18+17=73\)。注意,由于起点是 \(1\),所以自动获得第 \(1\) 格的分数 \(6\)。
对于 \(30\%\) 的数据有 \(1≤N≤30,1≤M≤12\)。
对于 \(50\%\) 的数据有 \(1≤N≤120,1≤M≤50\),且 \(4\) 种爬行卡片,每种卡片的张数不会超过 \(20\)。
对于 \(100\%\) 的数据有 \(1≤N≤350,1≤M≤120\),且 \(4\) 种爬行卡片,每种卡片的张数不会超过 \(40\);\(0≤a_i≤100,1≤i≤N,1≤b_i≤4,1≤i≤M\)。
看题解说四维数组,我去,这么想的?
设 fa,b,c,d 表示每种卡片分别用了 a 张、b 张、c 张、d 张时所得最大分数,那么此时应在第 a+2b+3c+4d+1 个格子,当前由 fa−1,b,c,d,fa,b−1,c,d,fa,b,c−1,d,fa,b,c,d−1 转移得到,再加上当前格子的分数。
设 gi 表示第 i 种卡片的数量,答案就是 fg1,g2,g3,g4。
代码:
int dp[50][50][50][50];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//
// freopen("E:/Code/C++/untitled1/input.txt","r",stdin);
// freopen("output.txt","w",stdout);
mem(dp);
int n,m;
cin >> n >> m;
int v[400],w[200],c[5];
mem(c);
f(i,0,n) cin >> v[i];
f(i,1,m+1)
{
cin >> w[i];
switch(w[i])
{
case 1: c[1]++;
break;
case 2: c[2]++;
break;
case 3: c[3]++;
break;
default:c[4]++;
}
}
dp[0][0][0][0] = v[0];
for(int i = 0;i <= c[1];++i)
for(int j = 0;j <= c[2];++j)
for(int k = 0;k <= c[3];++k)
for(int f = 0;f <= c[4];++f)
{
int t = i + j * 2 + k * 3 + f * 4;
if(i!= 0) dp[i][j][k][f] = max(dp[i][j][k][f],dp[i-1][j][k][f] + v[t]);
if(j!= 0) dp[i][j][k][f] = max(dp[i][j][k][f],dp[i][j-1][k][f] + v[t]);
if(k!= 0) dp[i][j][k][f] = max(dp[i][j][k][f],dp[i][j][k-1][f] + v[t]);
if(f!= 0) dp[i][j][k][f] = max(dp[i][j][k][f],dp[i][j][k][f-1] + v[t]);
}
cout << dp[c[1]][c[2]][c[3]][c[4]] << endl;
}