博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 10564 Paths through the Hourglass
阅读量:4496 次
发布时间:2019-06-08

本文共 3165 字,大约阅读时间需要 10 分钟。

UVA_10564

    我们可以用f[i][j][k]表示到第i行第j个格子时路径上值得和是否可以为k,为了保证记录的路径字典序最小的,我们可以将i由大向小循环。

    状态转移的思路还是很好想的,但是写起来有些蛋疼。

#include
#include
#define MAXD 50 #define MAXS 520 int N, S, f[MAXD][MAXD][MAXS], p[MAXD][MAXD][MAXS], num[MAXD], a[MAXD][MAXD]; long long int d[MAXD][MAXD][MAXS]; int init() {
int i, j, k; scanf("%d%d", &N, &S); if(!N && !S) return 0; for(i = 0; i < N; i ++) for(j = 0; j < N - i; j ++) {
scanf("%d", &a[i][j]); num[i] = N - i; } for(; i < 2 * N - 1; i ++) for(j = 0; j < i - N + 2; j ++) {
scanf("%d", &a[i][j]); num[i] = i - N + 2; } return 1; } void printpath(int k) {
int i, j, t; printf("%d ", k); for(i = 0, j = k, t = S; i < N - 1; i ++) {
if(p[i][j][t] == 0) {
printf("L"); t -= a[i][j --]; } else {
printf("R"); t -= a[i][j]; } } for(; i < 2 * N - 2; i ++) {
if(p[i][j][t] == 0) {
printf("L"); t -= a[i][j]; } else {
printf("R"); t -= a[i][j ++]; } } } void solve() {
int i, j, k; long long int res; memset(p, -1, sizeof(p)); memset(f, 0, sizeof(f)); memset(d, 0, sizeof(d)); for(i = 2 * N - 2, j = 0; j < num[i]; j ++) {
f[i][j][a[i][j]] = 1; d[i][j][a[i][j]] = 1; } for(i = 2 * N - 3; i >= N - 1; i --) for(j = 0; j < num[i]; j ++) {
for(k = 0; k <= S; k ++) if(f[i + 1][j][k]) {
f[i][j][k + a[i][j]] = 1; d[i][j][k + a[i][j]] += d[i + 1][j][k]; p[i][j][k + a[i][j]] = 0; } for(k = 0; k <= S; k ++) if(f[i + 1][j + 1][k]) {
d[i][j][k + a[i][j]] += d[i + 1][j + 1][k]; if(!f[i][j][k + a[i][j]]) {
f[i][j][k + a[i][j]] = 1; p[i][j][k + a[i][j]] = 1; } } } for(i = N - 2; i >= 0; i --) for(j = 0; j < num[i]; j ++) {
if(j) for(k = 0; k <= S; k ++) if(f[i + 1][j - 1][k]) {
f[i][j][k + a[i][j]] = 1; d[i][j][k + a[i][j]] += d[i + 1][j - 1][k]; p[i][j][k + a[i][j]] = 0; } if(j < num[i + 1]) for(k = 0; k <= S; k ++) if(f[i + 1][j][k]) {
d[i][j][k + a[i][j]] += d[i + 1][j][k]; if(!f[i][j][k + a[i][j]]) {
f[i][j][k + a[i][j]] = 1; p[i][j][k + a[i][j]] = 1; } } } res = 0; for(i = 0; i < num[0]; i ++) if(f[0][i][S]) {
if(!res) k = i; res += d[0][i][S]; } printf("%lld\n", res); if(res) printpath(k); printf("\n"); } int main() {
while(init()) solve(); return 0; }

转载于:https://www.cnblogs.com/staginner/archive/2011/12/04/2275595.html

你可能感兴趣的文章
【转载】 C#中常见的泛型集合类有哪些
查看>>
【转载】C#的DataTable使用NewRow方法创建新表格行
查看>>
【转载】 C#中ArrayList使用GetRange方法获取某一段集合数据
查看>>
【转载】C#如何获取DataTable中某列的数据类型
查看>>
【转载】如何查看本机电脑的公网IP
查看>>
【转载】C#的ArrayList使用IndexOf方法查找第一个符合条件的元素位置
查看>>
【转载】C#中ArrayList使用RemoveRange移除一整段数据
查看>>
【转载】C#使用typeof运算符获取对象变量的具体类型Type
查看>>
【转载】c# datatable 判断值是否存在
查看>>
【转载】C#中Datatable修改列名
查看>>
【转载】通过百度站长平台查看网站搜索流量及关键字
查看>>
【转载】如何查看自己网站的搜索引擎收录量和索引量
查看>>
【转载】通过搜狗站长平台查看网站的搜狗流量及搜索关键字
查看>>
【转载】Visual Studio2017如何打包发布Winform窗体程序
查看>>
【转载】Visual Studio中WinForm窗体程序如何切换.NET Framework版本
查看>>
【转载】Visual Studio2017如何设置打包发布的WinForm应用程序的版本号
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交死链
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交文章加快收录
查看>>
【转载】通过百度站长平台提交网站死链
查看>>
【转载】通过搜狗站长平台提交网站域名变更后的文章地址
查看>>