UVA - 10564 Paths through the Hourglass

传送门:https://vjudge.net/problem/UVA-10564

题目大意:给你一张形如沙漏一般的图,每一个格子有一个权值,问你有多少种方案可以从第一行走到最后一行,并且输出起点最靠前的方案,以及此方案的起点编号,起点相同则字典序最小。

题解:

  很容易想到一个DP,dp[i][j][S]代表到第i层,第j列,从第一层到这里的路径和为S的方案数,最后只要查询最后一行的方案数即可了。但是这样很不好输出方案!我们可能需要从终点向上dfs,但是又无法保证起点编号最小以及字典序最小。但是我们能从终点向上dfs,那么如果我们反过来DP呢?可行啊,这样就可以从起点向终点dfs了,贪心选择可行的路径即可。
  需要注意的是上下两个一半的沙漏的转移一个是到j与j+1,一个是j与j-1,要考虑清楚细节!

 1 #include<queue>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define RG register
 8 #define LL long long
 9 #define fre(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
10 using namespace std;
11 const int MAXN=22,MAXS=599;
12 int n;
13 LL ans,S;
14 LL a[MAXN*2][MAXN],dp[MAXN*2][MAXN][MAXS];
15 void dfs(int x,int y,int sum);
16 int main()
17 {
18    while(scanf("%d%lld",&n,&S)!=EOF)
19       {
20          if(n+S==0)break;
21          for(int i=1;i<=n;i++) for(int j=1;j<=n-i+1;j++) scanf("%lld",&a[i][j]);
22          for(int i=n+1;i<2*n;i++) for(int j=1;j<=i-n+1;j++) scanf("%lld",&a[i][j]);
23          memset(dp,0,sizeof dp);
24          for(int i=1;i<=n;i++) dp[n*2-1][i][a[n*2-1][i]]=1;
25          for(int i=n*2-2;i>=n;i--)
26             for(int j=1;j<=i-n+1;j++)
27                for(int k=0;k<=S;k++)
28                   {
29                      if(dp[i+1][j][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j][k];
30                      if(dp[i+1][j+1][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j+1][k];
31                   }
32          for(int i=n-1;i>=1;i--)
33             for(int j=1;j<=n-i+1;j++)
34                for(int k=0;k<=S;k++)
35                   {
36                      if(dp[i+1][j][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j][k];
37                      if(dp[i+1][j-1][k] && k+a[i][j]<=S) dp[i][j][k+a[i][j]]+=dp[i+1][j-1][k];
38                   }
39          ans=0; for(int i=1;i<=n;i++) ans+=dp[1][i][S]; printf("%lld\n",ans);
40          for(int i=1;i<=n;i++)
41             if(dp[1][i][S])
42                {
43                   printf("%d ",i-1);
44                   int x=1,y=i,sum=S;
45                   while(x<n*2-1)
46                      {
47                         if(x<n)
48                            {
49                               if(dp[x+1][y-1][sum-a[x][y]])  sum-=a[x][y],y--,printf("L");
50                               else sum-=a[x][y],printf("R");
51                            }
52                         else
53                            {
54                               if(dp[x+1][y][sum-a[x][y]]) sum-=a[x][y],printf("L");
55                               else sum-=a[x][y],y++,printf("R");
56                            }
57                         x++;
58                      }
59                   break;
60                }
61          printf("\n");
62       }
63    return 0;
64 }

 

转载于:https://www.cnblogs.com/D-O-Time/p/7701377.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 智慧社区背景与挑战 随着城市化的快速发展,社区面临健康、安全、邻里关系和服务质量等多方面的挑战。华为技术有限公司提出智慧社区解决方案,旨在通过先进的数字化技术应对这些问题,提升城市社区的生活质量。 2. 技术推动智慧社区发展 技术进步,特别是数字化、无线化、移动化和物联化,为城市社区的智慧化提供了可能。这些技术的应用不仅提高了社区的运行效率,也增强了居民的便利性和安全性。 3. 智慧社区的核心价值 智慧社区承载了智慧城市的核心价值,通过全面信息化处理,实现对城市各个方面的数字网络化管理、服务与决策功能,从而提升社会服务效率,整合社会服务资源。 4. 多层次、全方位的智慧社区服务 智慧社区通过构建和谐、温情、平安和健康四大社区模块,满足社区居民的多层次需求。这些服务模块包括社区医疗、安全监控、情感沟通和健康监测等。 5. 智慧社区技术框架 智慧社区技术框架强调统一平台的建设,设立数据中心,构建基础网络,并通过分层建设,实现平台能力及应用的可持续成长和扩展。 6. 感知统一平台与服务方案 感知统一平台是智慧社区的关键组成部分,通过统一的RFID身份识别和信息管理,实现社区服务的智能化和便捷化。同时,提供社区内外监控、紧急救助服务和便民服务等。 7. 健康社区的构建 健康社区模块专注于为居民提供健康管理服务,通过整合医疗资源和居民接入,实现远程医疗、慢性病管理和紧急救助等功能,推动医疗模式从治疗向预防转变。 8. 平安社区的安全保障 平安社区通过闭路电视监控、防盗报警和紧急求助等技术,保障社区居民的人身和财产安全,实现社区环境的实时监控和智能分析。 9. 温情社区的情感沟通 温情社区着重于建立社区居民间的情感联系,通过组织社区活动、一键呼叫服务和互帮互助平台,增强邻里间的交流和互助。 10. 和谐社区的资源整合 和谐社区作为社会资源的整合协调者,通过统一接入和身份识别,实现社区信息和服务的便捷获取,提升居民生活质量,促进社区和谐。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值