2014蓝桥杯 地宫取宝 &&hdu 4597 四维数组状态记忆化
2016-03-18 23:21
831 查看
地宫取宝
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
【数据格式】
输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
例如,输入:
2 2 2
1 2
2 1
程序应该输出:
2
再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型
本题是一个状态推移的dfs题目,但需要设置数组d[][][][]进行记忆化搜索节省时间。但是本题有个巨大的陷阱,一开始忽略了,调试了很长时间总是不成功只对前两个测试用例,原来是一开始dfs(1,1,0,-1)一开始价值要为-1才行,因为图中map[][]可以为0,下面是我的AC代码
Problem Description
Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from either pile, and the score of the card will be added to his total score. Alice
and Bob are both clever enough, and will pick up cards to get as many scores as possible. Do you know how many scores can Alice get if he picks up first?
Input
The first line contains an integer T (T≤100), indicating the number of cases.
Each case contains 3 lines. The first line is the N (N≤20). The second line contains N integer ai (1≤ai≤10000). The third line contains N integer bi (1≤bi≤10000).
Output
For each case, output an integer, indicating the most score Alice can get.
Sample Input
Sample Output
dp[la][ra][lb][rb]记录的是在a的区间为la~ra,b的区间为lb~rb的情况下,某人采取最好策略的总分数
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
【数据格式】
输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
例如,输入:
2 2 2
1 2
2 1
程序应该输出:
2
再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型
本题是一个状态推移的dfs题目,但需要设置数组d[][][][]进行记忆化搜索节省时间。但是本题有个巨大的陷阱,一开始忽略了,调试了很长时间总是不成功只对前两个测试用例,原来是一开始dfs(1,1,0,-1)一开始价值要为-1才行,因为图中map[][]可以为0,下面是我的AC代码
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int map[60][60]; int n,m,k; int d[55][55][20][20]; int dfs(int x,int y,int num,int w) { if(d[x][y][num][w+1]!=-1) return d[x][y][num][w+1]; if(x==n&&y==m) { if(num==k||num==k-1&&map[x][y]>w) d[x][y][num][w+1]=1; else d[x][y][num][w+1]=0; return d[x][y][num][w+1]; } if(num>k) return 0; int t=0; if(y<m) { if(map[x][y]>w) { t+=dfs(x,y+1,num+1,map[x][y]); t=t%1000000007; t+=dfs(x,y+1,num,w); t=t%1000000007; } else { t+=dfs(x,y+1,num,w); t=t%1000000007; } } if(x<n) { if(map[x][y]>w) { t+=dfs(x+1,y,num+1,map[x][y]); t=t%1000000007; t+=dfs(x+1,y,num,w); t=t%1000000007; } else { t+=dfs(x+1,y,num,w); t=t%1000000007; } } d[x][y][num][w+1]=t; return d[x][y][num][w+1]; } int main() { memset(d,-1,sizeof(d)); cin>>n>>m>>k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>map[i][j]; d[1][1][0][0]=dfs(1,1,0,-1); cout<<d[1][1][0][0]<<endl; return 0; }
Problem Description
Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from either pile, and the score of the card will be added to his total score. Alice
and Bob are both clever enough, and will pick up cards to get as many scores as possible. Do you know how many scores can Alice get if he picks up first?
Input
The first line contains an integer T (T≤100), indicating the number of cases.
Each case contains 3 lines. The first line is the N (N≤20). The second line contains N integer ai (1≤ai≤10000). The third line contains N integer bi (1≤bi≤10000).
Output
For each case, output an integer, indicating the most score Alice can get.
Sample Input
2 1 23 53 3 10 100 20 2 4 3
Sample Output
53 105
dp[la][ra][lb][rb]记录的是在a的区间为la~ra,b的区间为lb~rb的情况下,某人采取最好策略的总分数
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define LL long long using namespace std; int n; int a[30],b[30]; int d[30][30][30][30]; int dfs(int al,int ar,int bl,int br,int sum) { if(d[al][ar][bl][br]!=-1) return d[al][ar][bl][br]; if(ar<al&&br<bl)//必须是&& return 0; int maxx=0; if(al<=ar) { maxx=max(maxx,sum-dfs(al+1,ar,bl,br,sum-a[al])); maxx=max(maxx,sum-dfs(al,ar-1,bl,br,sum-a[ar])); } if(bl<=br) { maxx=max(maxx,sum-dfs(al,ar,bl+1,br,sum-b[bl])); maxx=max(maxx,sum-dfs(al,ar,bl,br-1,sum-b[br])); } return d[al][ar][bl][br]=maxx; } int main() { int T; cin>>T; while(T--) { int sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } for(int j=1;j<=n;j++) { cin>>b[j]; sum+=b[j]; } memset(d,-1,sizeof(d)); cout<<dfs(1,n,1,n,sum)<<endl; } return 0; }
相关文章推荐
- Android中四大组件总结
- Java中String类(字符串操作)的10个常见问题和解决方法
- 多线程中跨线程访问的解决方法
- 在中国,程序员的职业生涯有多长?
- Java命名规范
- composer 安装 laravel 日志
- 老罗Looper(23)例子讲述Looper与Message,线程和Handler关系
- 删除链表中重复的结点
- 从n到m,有-1和*2两种操作。问最少走几步
- mac jdk原因导致 maven命令无法执行
- 13. 精确计算使用BigDecimal
- gcc命令大全
- 第一次上机实验1-2
- Linux内存管理之mmap详解
- Android——Activity和Intent及Activity的生命周期
- 监听滚动window.onscroll scrlltop被卷去的头部
- 手写毛笔字效果-手机版
- DNS的功能和原理?(总结)
- 成长需要环境
- HDU 1312 Red and Black(经典搜索,DFS&BFS三种方式)