时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。 输入格式 输入的第一行包含一个整数n,表示商店的数量。 输出格式 输出一行,包含n个正整数,依次表示每个商店第一天的菜价。 样例输入 8 样例输出 2 2 2 1 6 5 16 10 数据规模和约定 对于30%的评测用例,2<=n<=5,第二天每个商店的菜价为不超过10的正整数; |
这道题递归很好拿分,看别人用了几步剪枝能100,厉害。我用python写的带剪枝的结果还超时,就算了。。。
正解是用差分约束系统转换成最短路问题,网上看完基础知识做这个题很顺利,不过python的spfa写的着实让我头疼。。
class node:
pass
def add(u,v,w):
global edg,head,cnt #python 在函数中要改变全局变量的值,需加
ed = node()
ed.v = v
ed.w = w
ed.next = head[u]
edg.append(ed)
head[u] = cnt
cnt+=1
pass #这个gp pass语句毛用没有,本以为是在py里return空的意思
def spfa(s):
queue = []
queue.append(s)
vis[s]=1
for i in range(n): #抽象一个大源点,所有点入队,置dist为0,表示大源点联通所有si,边权为0,防止图不连通
dist[i]=0
rao[i]=1
#print(queue)
while not len(queue)==0:
u = queue[0]
queue.pop(0)
#print(queue)
#break
vis[u] = 0
k = head[u]
while not k+1==0:
v = edg[k].v
if dist[v]<dist[u]+edg[k].w:
dist[v]=dist[u]+edg[k].w
if vis[v]==0:
vis[v]=1
queue.append(v)
rao[v]+=1
if rao[v]>n: #当进队次数大于n时,说明是负环,即无解
return 0
k=edg[k].next
return 1
while True:
try:
cnt = 0
rao = [0 for _ in range(3005)]
vis = [0 for _ in range(3005)]
dist = [0 for _ in range(3005)]
edg = []
head = [-1 for _ in range(12200)]
p = [0 for _ in range(3005)]
n = int(input())
p[1:]=map(int,input().split())
#print(p)
for i in range(n-2): #3 0 /4 1/5 2....
add(i,i+3,3*p[i+2])
add(i+3,i,-(3*p[i+2]+2))
#print(-(3*p[i+2]+2))
add(2,0,-(2*p[1]+1))
add(0,2,2*p[1])
add(n,n-2,-(2*p[n]+1))
add(n-2,n,2*p[n])
#print(head)
for i in range(n): #每个数都至少是1
add(i,i+1,1)
#print(1)
if spfa(0):
for i in range(1,n):
print(dist[i]-dist[i-1],end=" ")
print(dist[n]-dist[n-1])
except:
break