Intervals
题意:给出N个区间(),求一个最短的序列使得序列包含了区间
里的至少
个数。输出最短的长度。
定义 为前x个数里包含的数的个数,那么根据题意有
,此外
即
还有
。 这样就可以通过差分约束跑spfa求最长路得出答案了。
#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <cstring>
#include <set>
#define ll long long
#define lld unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
const int MAXN = 51111;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int maxn=100010;
struct Edge {
int from, to, dist;
};
struct SPFA {
int n, m;
vector <Edge> edges;
vector <int> G[MAXN];
bool vis[MAXN];
int d[MAXN], p[MAXN];
int cnt[MAXN];
void init(int n) {
this -> n = n;
for (int i = 0; i < n; i++) G[i].clear();
edges.clear();
}
void addedge(int from, int to, int dist) {
edges.push_back((Edge) {from, to, dist});
m = edges.size();
G[from].push_back(m - 1);
}
void solve(int l,int r) {
queue <int> q;
memset (vis, false, sizeof vis);
memset (cnt, 0, sizeof(cnt));
for (int i = l; i <= r; i++)
{
d[i]=0;vis[i]=true;
q.push(i);
}
while (!q.empty ()) {
int u = q.front (); q.pop ();
vis[u] = false;
for (int i = 0; i < (int)G[u].size(); i++) {
Edge& e = edges[G[u][i]];
int v = e.to, w = e.dist;
if (d[v] < d[u] + w) {
d[v] = d[u] + w;
if (!vis[v]) {
vis[v] = true; q.push (v);
}
}
}
}
}
} spfa;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int l=50000;
int r=0;
spfa.init(50001);
for(int i=1; i<=n; i++)
{
int u,v,c;
scanf("%d %d %d",&u,&v,&c);
spfa.addedge(u-1,v,c);
l=min(l,u-1);
r=max(r,v);
}
for(int i=l+1; i<=r; i++)
{
spfa.addedge(i-1,i,0);
spfa.addedge(i,i-1,-1);
}
spfa.solve(l,r);
printf("%d\n",spfa.d[r]);
}
return 0;
}
Cashier Employment
题意转化:一条长度为24的线段上有24个点,给出N个起点和长度为8的线,求最少的线使得每个点都能被覆盖次。
定义 为1~i里有多少起点。则有关系
,
,
,
即
。其中num[i]为在i时刻实际最多能有的起点。
//#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <cstring>
#include <set>
#define ll long long
#define lld unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
const int MAXN = 51111;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int maxn=100010;
struct Edge {
int from, to, dist;
};
struct SPFA {
int n, m;
vector <Edge> edges;
vector <int> G[MAXN];
bool vis[MAXN];
int d[MAXN], p[MAXN];
int cnt[MAXN];
void init(int n) {
this -> n = n;
for (int i = 0; i < n; i++) G[i].clear();
edges.clear();
}
void addedge(int from, int to, int dist) {
edges.push_back((Edge) {from, to, dist});
m = edges.size();
G[from].push_back(m - 1);
}
bool solve(int s) {
queue <int> q;
memset (vis, false, sizeof vis);
memset (cnt, 0, sizeof(cnt));
fill(d,d+25,-inf);
d[s]=0;
q.push(s);
while (!q.empty ()) {
int u = q.front (); q.pop ();
vis[u] = false;
for (int i = 0; i < (int)G[u].size(); i++) {
Edge& e = edges[G[u][i]];
int v = e.to, w = e.dist;
if (d[v] < d[u] + w) {
d[v] = d[u] + w;
if (!vis[v]) {
vis[v] = true; q.push (v);
if(++cnt[v]>25) return false;
}
}
}
}
return true;
}
} spfa;
int R[100];
int num[100];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(num,0,sizeof num);
for(int i=1;i<=24;i++) scanf("%d",&R[i]);
int N;
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
int x;scanf("%d",&x);
num[x+1]++;
}
bool flag=0;
for(int j=0; j<=N; j++)
{
spfa.init(100);
for(int i=1; i<=24; i++)
{
spfa.addedge(i-1,i,0);
spfa.addedge(i,i-1,-num[i]);
if(i>=8)
{
spfa.addedge(i-8,i,R[i]);
}
else
{
spfa.addedge(16+i,i,R[i]-j);
}
}
spfa.addedge(0,24,j);
if(spfa.solve(0)&&spfa.d[24]==j)
{
printf("%d\n",j);
flag=1;break;
}
}
if(flag==0) printf("No Solution\n");
}
return 0;
}