[csp-201809-4]再卖菜 差分约束or记忆化搜索

先更新第一个做法:差分约束

转化成最长路,求出的每一个解是满足差分方程的最小值

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N=3100;
 5 struct node{
 6     int x,y,d,next;
 7 }a[2*N];
 8 int n,al,first[N],b[N],s[N];
 9 bool vis[N];
10 queue<int> q;
11
12 void ins(int x,int y,int d)
13 {
14     al++;
15     a[al].x=x;a[al].y=y;a[al].d=d;
16     a[al].next=first[x];first[x]=al;
17 }
18
19 void build_edge()
20 {
21     al=0;
22     memset(first,0,sizeof(first));
23     ins(0,2,2*b[1]);
24     ins(2,0,-(2*b[1]+1));
25     for(int i=2;i<=n-1;i++)
26     {
27         ins(i-2,i+1,3*b[i]);
28         ins(i+1,i-2,-(3*b[i]+2));
29     }
30     ins(n-2,n,2*b[n]);
31     ins(n,n-2,-(2*b[n]+1));
32     for(int i=1;i<=n;i++) ins(i-1,i,1);
33 }
34
35 void spfa()
36 {
37     while(!q.empty()) q.pop();
38     memset(s,0,sizeof(s));
39     memset(vis,0,sizeof(vis));
40     s[0]=0;vis[0]=1;q.push(0);
41     while(!q.empty())
42     {
43         int x=q.front();q.pop();
44         for(int i=first[x];i;i=a[i].next)
45         {
46             int y=a[i].y;
47             if(s[y]<s[x]+a[i].d)
48             {
49                 s[y]=s[x]+a[i].d;
50                 if(!vis[y])
51                 {
52                     vis[y]=1;
53                     q.push(y);
54                 }
55             }
56         }
57         vis[x]=0;
58     }
59 }
60
61 int main()
62 {
63     //freopen("a.in","r",stdin);
64     scanf("%d",&n);
65     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
66     build_edge();
67     spfa();
68     for(int i=1;i<=n;i++)
69         printf("%d ",s[i]-s[i-1]);printf("\n");
70     return 0;
71 }

原文地址:https://www.cnblogs.com/KonjakJuruo/p/10077196.html

时间: 2024-10-03 18:16:11

[csp-201809-4]再卖菜 差分约束or记忆化搜索的相关文章

CCF(再卖菜60分)爆搜+记忆化搜索+差分约束

201809-4 再卖菜 我使用的是爆搜解决,只得了60分. 记忆化搜索 差分约束 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; int n; int a[303]; int b[303]; bool flag=false; void dfs(int k,int now,

ccf 201809-4 再卖菜

这题一开始不知道剪枝这种操作,只会傻傻地dfs. 然后dfs递归写80分超时,非递归写70分超时(纳尼?我一直以为非递归算法在时间上会更优秀一些,为什么会这样?!!) 剪一下枝就都能过了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 int a[300],b[300]; 7 bool vis[30

bzoj2788 festival 差分约束

填坑中--链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2788 题意: 有$n$个正整数$X1,X2,...,Xn$,再给出$m1+m2$个限制条件,限制分为两类:1. 给出$a,b(1<=a,b<=n)$,要求满足$Xa + 1 = Xb$2. 给出$c,d (1<=c,d<=n)$,要求满足$Xc <= Xd$在满足所有限制的条件下,求集合${Xi}$大小的最大值. 首先看情况我们也知道是差分约束-- 但是这个差分

hdu 1364(差分约束)

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12056   Accepted: 4397 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin

poj3169 最短路(差分约束)

题意:一个农夫有n头牛,他希望将这些牛按照编号 1-n排成一条直线,允许有几头牛站在同一点,但是必须按照顺序,有一些牛关系比较好,希望站的距离不超过某个值,而有一些牛关系不太好,所以希望站的距离大于等于某个值,问1号牛和n号牛之间的最远距离是多少. 差分约束的裸题,对于 d[v] - d[u] ≤ w 建立权值为 w 的单向边 e(u,v),对于 d[v] - d[u]  ≥ w 建立权值为 -w 的单向边 e(v,u),然后再根据牛必须按顺序排列建立权值为 0 的边 e(i+1,i),然后最短

POJ 3169 Layout (差分约束+SPFA)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6832   Accepted: 3292 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

差分约束:布局

题目描述  Description 当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些.FJ有N(2<=N<=1000)头奶牛,编号从1到N,沿一条直线站着等候喂食.奶牛排在队伍中的顺序和它们的编号是相同的.因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上.即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标. 一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数L.另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数D.给

SGU 298 King Berl VI 差分约束 并使得min(dis[n]-dis[1])

题目链接:点击打开链接 题意: 给定n个点m条约束. 下面输出 u v x 表示: dis[u] - dis[v] >= x 然后建图就是 u->v 边权为-x 输出一个解满足 -10000<= dis[i] <= 10000. 若有多解输出一个 dis[n] - dis[1] 最小的解. 思路: 正图求个最大解,反图求个最小解. 对于一个点的 最大解<最小解,则差分约束无解. 题目要求dis[n]-dis[1]最小,那就令dis[n]为其最小解,dis[1]为其最大解,再s

zoj2770 Burn the Linked Camp --- 差分约束

有n个营地,每个营地至多容纳Ci人,给出m个条件:第i到第j个营地之间至少有k人. 问n个营地总共至少有多少人. 此题显然差分约束,要求最小值,则建立x-y>=z方程组,建图求最长路. 用d[i]表示[1,i]个帐篷中一共多少人,根据题意可得到不等关系: 1.0<=d[i]-d[i-1]<=C[i] 2.d[j]-d[i]>=k 此外,我们添加0为附加结点,则0到其他点也要建边. 再求解0为源点的最长路即可. 我的坑点是,判负环返回0,否则返回d[n]. 而d[n]本身就可能是0.