321
社区成员




一个小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
输入一个正整数n代表房屋的数量(n≤100),接着输入n个非负整数代表每间房屋的现金数量
额。一共最多100个数字,暴力计算即可
n = int(input())
arr = list(map(int,input().split()))
ans = 0
def f(v,r):
global ans
if v > ans:
ans = v
l = len(r)
if l == 0:
return
f(v + r[0],r[2:])
if l > 1:
f(v + r[1],r[3:])
f(0,arr)
print(ans)
要么隔着一家偷,要么隔着两家偷,被偷的最后一家要么是倒数第一家,要么是倒数第二家。跟那个青蛙跳台阶一样的。
今天又碰到这个了,那就来个不那么暴力的
n = int(input())
arr = list(map(int,input().split()))
dp = [0] * n
dp[0] = arr[0]
if n > 1:
dp[1] = max(arr[:2])
for i in range(2,n):
dp[i] = max(dp[i - 1],dp[i - 2] + arr[i])
print(dp[-1])
可以不那么暴力的。
假设所有人家都有钱,则
新建数组s[],其中s[i]用来记录从头开始到第i家能抢到的最多钱数
新增指示数组a[],其中a[i]用来记录可以让s[i]成立的所有方案中,最后一家倒霉蛋最靠前的位置(显然了,a[i]要么是i, 要么是i-1)
于是,如果我已经有s[0],...., s[i]以及a[0],...,a[i]的所有值,
则很容易的推导出s[i+1]和a[i+1]。
若a[i]<i,则
s[i+1]=s[i]+arr[i+1]
a[i+1]=i+1
若a[i]=i, 且s[i-1]+arr[i+1]<=s[i]则
s[i+1]=s[i]
a[i+1]=i
若a[i]=i, 且s[i-1]+arr[i+1]>s[i]则
s[i+1]=s[i-1]+a[i+1]
a[i+1]=i+1
一路推算到底,最后的s[N]就是解。
然后考虑到每一步推算的过程中,真正用到的其实只有s[i-1], s[i], a[i-1], a[i]这4个变量,所以新增的数组s[]和a[]可以用4个普通变量来代替以节省空间。