列表

详情


NC208144. ar采蘑菇

描述

给你一个n*m的网格地图,该地图每个相交处都是一个点,ar最初的初始点在地图的左下角(0,0),他想要到地图的右上角(n,m)点去采蘑菇,但他不想单纯的向上或向右走,因为他觉得这样太简单了,所以他给自己的行走方式做出了一定的限制,他规定自己只能用他喜欢的k种行走方式行走,现在他想知道自己走到右上角(n,m)点最多能使用多少种不同的行走方式?

输入描述

第一行输入一个T,表示测试用例的数量  1 ≤ T ≤ 50
在每个测试用例中,第一行输入3个数n,m,k  0 ≤ n,m ≤ 100, 1 ≤ k ≤ 5
接下来k行表示ar喜欢的k种行走方式,行走方式中只包含'U','R'两种字符,每种行走方式均不同  1 ≤ length ≤ 100

输出描述

对于每组测试用例,输出最多能使用的不同的行走方式

示例1

输入:

1
2 3 3
RR
U
RUR

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 54ms, 内存消耗: 616K, 提交时间: 2020-06-23 22:40:44

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
#define int long long 
int cnt[10][2]; int ans; int n, m, k;
void dfs(int x, int y, int now, int p) {
	if (x > n || y > m) return;
	if (x == n && y == m) {
		ans = max(p, ans);
		return;
	}
	for (int i = now + 1; i <= k; i++) {
		for (int j = 1; j <= 100; j++) {
			int c = x + cnt[i][0]*j;
			int d = y + cnt[i][1]*j;
			if (c > n || d > m) break;
			dfs(c, d, i, p + 1);	
		}
	}
}
signed main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int t; cin >> t;
	while (t--) {
		cin >> n >> m >> k; ans = 0;
		for (int i = 1; i <= k; i++) {
			string s; cin >> s;
			int x = 0, y = 0;
			for (int j = 0; j < s.size(); j++) {//记录每种行走方式能走的距离
				if (s[j] == 'U') y++;
				else x++;
			}
			cnt[i][0] = x; cnt[i][1] = y;
		}
		dfs(0, 0, 0, 0);
		cout << ans << endl;
	}
	return 0;
}

pypy3(pypy3.6.1) 解法, 执行用时: 722ms, 内存消耗: 56660K, 提交时间: 2020-06-22 16:37:54

for _ in range(int(input())):
	n, m, k = map(int, input().split())
	n += 1
	m += 1
	dp = [[[0]*(1<<5) for i in range(101)] for j in range(101)]
	delta = [[0]*2 for i in range(5)]
	dp[0][0][0] = 1
	for kk in range(k):
		x = input()
		dx, dy = 0, 0
		for xx in x:
			if xx=='R':
				dx += 1
			else:
				dy += 1
		delta[kk][0], delta[kk][1] = dx, dy
	for i in range(n):
		for j in range(m):
			for mask in range(1<<k):
				for kk in range(k):
					prei, prej = i - delta[kk][0], j - delta[kk][1]
					if prei>=0 and prej>=0 and prei<n and prej<m:
						dp[i][j][mask|(1<<kk)] |= dp[prei][prej][mask]
	ans = 0
	for mask in range(1<<k):
		bit = 0
		for i in range(k):
			if (mask>>i)&1:
				bit += 1
		if bit>ans and dp[n-1][m-1][mask]:
			ans = bit
	print(ans)

C++11(clang++ 3.9) 解法, 执行用时: 6ms, 内存消耗: 616K, 提交时间: 2020-06-23 15:37:30

#include<bits/stdc++.h>
using namespace std;

int n,m,k,ans,dx[5],dy[5],Max[105][105];
void DFS(int x,int y,int z)
{
	int i,j,X,Y,Z;
	if(x==n&&y==m)return;
	for(i=0;i<k;i++)
	{
		X=x+dx[i],Y=y+dy[i],Z=z|(1<<i),j=__builtin_popcount(Z);
		if(X<=n&&Y<=m&&j>Max[X][Y])Max[X][Y]=j,DFS(X,Y,Z);
	}
}
int main()
{
    int i,j,T;
    char R[5][105];
    scanf("%d",&T);
    while(T--)
    {
    	scanf("%d%d%d",&n,&m,&k);
    	memset(dx,0,sizeof(dx)),memset(dy,0,sizeof(dy));
    	for(i=0;i<k;i++)scanf("%s",R[i]);
    	for(i=0;i<k;i++)
    	    for(j=0;R[i][j]!='\0';j++)
    	    {
    	    	if(R[i][j]=='R')dx[i]++;
			    else dy[i]++;
			}
    	memset(Max,0,sizeof(Max)),DFS(0,0,0);
    	printf("%d\n",Max[n][m]);
	}
}

上一题