题目1 棋盘寻宝
两种思路:(1)二维的动态规划(解题报告)(2)深搜(自己).动态规划只需要0ms,而深搜却需要50ms。
动态规划需要满足的条件:点击打开链接
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int map[8][8], dp[8][8];
int main()
{
int i, j;
//freopen("/home/lsy/Desktop/2.txt", "r", stdin);
while(scanf("%d", &map[0][0]) != EOF) {
for(i=0; i<8; i++) {
for(j=0; j<8; j++) {
dp[i][j] = 0;
if(i==0 && j==0) continue;
scanf("%d", &map[i][j]);
}
}
for(i=0; i<8; i++) {
for(j=0; j<8; j++) {
if(i==0 && j==0) {dp[i][j] = map[i][j];continue;}
if(i==0) dp[i][j] = dp[i][j-1] + map[i][j];
else if(j==0) dp[i][j] = dp[i-1][j] + map[i][j];
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + map[i][j];
}
}
printf("%d\n", dp[7][7]);
}
return 0;
}
题目4
棋盘寻宝扩展
思路:深搜+剪枝
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int map[8][8];
int visit[8][8];
int go[2][2] = { {0, 1}, {1, 0} };
int T, maxL = 0;
void dfs(int x, int y, int num) {
if(num > T) return;
if(x == 7 && y == 7) {
if(maxL < num) {
maxL = num;
//printf("maxL = %d\n", maxL);
}
return;
}
int i;
for(i=0; i<2; i++) {
int nx = x + go[i][0];
int ny = y + go[i][1];
if(nx<0 || nx >7 || ny<0 || ny>7) continue;
if(visit[nx][ny] == 1) continue;
visit[nx][ny] = 1;
dfs(nx, ny, num+map[nx][ny]);
visit[nx][ny] = 0;
}
}
int main()
{
int i, j;
//freopen("/home/lsy/Desktop/2.txt", "r", stdin);
while(scanf("%d", &T) != EOF) {
maxL = 0;
for(i=0; i<8; i++)
for(j=0; j<8; j++) {
visit[i][j] = 0;
scanf("%d", &map[i][j]);
}
visit[0][0] = 1;
dfs(0, 0, map[0][0]);
if(maxL == 0) printf("-1\n");
else printf("%d\n", maxL);
}
return 0;
}
题目2 最长不重复子串
思路:和求最大子串的和一样。无非是加了个限制条件。O(n)的算法。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 10010;
int hash[27][2];
char str[MAXN];
int main()
{
int maxL, len, i, pos;
while(scanf("%s", str) != EOF) {
maxL = len = 0;
memset(hash, 0, sizeof(hash));
pos = 1;
for(i=0; str[i]; i++) {
if(1 == hash[str[i]-'a'][0]) {
if(pos < hash[str[i]-'a'][1]) pos = hash[str[i]-'a'][1];
len =i - pos;
len++;
hash[str[i]-'a'][1] = i+1;
} else {
len ++;
hash[str[i]-'a'][0] = 1;
hash[str[i]-'a'][1] = i+1;
}
//printf("len = %d\n", len);
if(maxL < len) maxL = len;
}
//printf("len = %d\n", len);
printf("%d\n", maxL);
}
return 0;
}
题目3 货币面值
思路:当时用的深搜,果断TLE。后来看了解题报告,才知道是01背包问题。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 6000;
int A[110], dp[MAXN];
int main() {
int i, j, m, n;
freopen("/home/lsy/Desktop/2.txt", "r", stdin);
while(scanf("%d", &n) != EOF) {
m = 0;
memset(dp, 0, sizeof(dp));
for(i=0; i<n; i++) {
scanf("%d", &A[i]);
m += A[i];
}
dp[0] = 1;
for(i=0; i<n; i++) {
//dp[A[i]] = 1;//这是值得注意的地方,想想???
for(j=m; j>=A[i]; j--) {//逆序。为什么不是顺序??
if(dp[j-A[i]]) dp[j] = 1;
}
}
for(i=0; i<m+2; i++)
if(dp[i] == 0) break;
printf("%d\n", i);
}
return 0;
}
总结:本次题目相对来说比较简单。都有思路。对7月份的,有一道题(Manacher算法,求最长回文串)完全没听说过。看着这么多AK的,看来自己应该加把劲了。