一道可以用各种各样的办法做的(水)题

在这里就介绍两种做法

题意:

自己看看吧,很明显的意思,就是求前i个人最少有多少个话筒。

解法1:差分约束

设\(dis[i]\)表示前\(i\)个人最少有多少个话筒

根据题目意思每个人都只能有一个话筒 所以 \(dis[i[+1>=dis[i+1] dis[i+1]>=dis[i]\)

\(a_i\)到\(b_i\)至少有\(c_i\)个 所以 \(dis[a_i-1]+c_i>=dis[b_i]\)

转换一下跑一遍最长路即可。

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath> #define N 30010
#define M 5050
#define INF 214748364 using namespace std; struct edge {
int to;
int from;
int data;
}e[N * 2 + 1];
int head[N],cnt;
int dis[N],m,n;
bool vis[N];
queue<int > q; inline void add_edge(int x,int y,int z) {
e[++cnt].from = y;
e[cnt].data = z;
e[cnt].to = head[x];
head[x] = cnt;
}
void spfa() {
for(int i = 1 ; i <= n ; i++)
dis[i] = -19260817;
dis[1] = 0;
q.push(1);
vis[1] = true;
while(!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u] ; i ; i = e[i].to) {
int v = e[i].from;
if(dis[u] + e[i].data > dis[v]) {
dis[v] = dis[u] + e[i].data;
if(!vis[v]) {
q.push(v);
vis[v] = true;
}
}
}
}
} int main() {
//n = read(), m = read();
scanf("%d%d",&n,&m);
while(m--) {
//int l = read(), r = read(), k = read();
int u , v , w;
scanf("%d%d%d",&u,&v,&w);
add_edge(u - 1 , v , w);
}
for(int i = 1 ; i <= n ; i++) {
add_edge(i - 1 , i , 0);
add_edge(i , i - 1 , -1);
}
spfa();
printf("%d\n", dis[n]);
return 0;
}

啥,你不想写SPFA。不过没关系,我们还有另一种做法。

解法2:贪心

我们可以先按所有声部的右端点排序,再进行从后到前的顺序选取拿话筒的人。很显然,如果我们从后往前选取,就会尽量满足后面人的需求,这样就能达到最小值。

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std;
const int N = 31000; struct node {
int a;
int b;
int c;
}e[N];
int m,n,ans;
int vis[N]; inline bool cmp(node x,node y) {
if(x.b != y.b)
return x.b < y.b;
return x.a < y.a;
}
void init() {
scanf("%d%d",&n,&m);
for(int i = 1 ; i <= m ; i++)
scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
}
void work() {
sort(e+1 , e + m + 1 , cmp);
for(int i = 1 ; i <= m ; i++) {
int cnt = 0;
for(int j = e[i].b ; j >= e[i].a ; j--) {
if(vis[j]) cnt++;
}
if(cnt > e[i].c) continue;
else {
for(int j = e[i].b ; (j >= e[i].b - e[i].c + 1 && cnt < e[i].c) ; j--) {
if(!vis[j]) vis[j] = 1 , cnt++ , ans++;
}
}
}
printf("%d\n",ans);
} int main() {
init();
work();
return 0;
}

最新文章

  1. myeclipse 内存不够用报错PermGen space 和 An internal error has occurred.
  2. jQuery使用FormData上传文件
  3. [游戏模版8] Win32 透明贴图
  4. Ubuntu 安装搜狗拼音及fcitx
  5. SCCM 部署操作系统 ,提示权限问题,报错:0xc00000098
  6. VS2013 :IntelliSense: 不允许使用不完整的类型
  7. jquery中table里面的tr里的input添加一行,并且第一列autoincrement
  8. C#单元测试工具包:MvcContrib
  9. 读书共享 Primer Plus C-part11
  10. SSM-MyBatis-18:Mybatis中二级缓存和第三方Ehcache配置
  11. MySQL之字符集
  12. Oracle常用语句
  13. 关于 DotNetCore 的自定义权限管理
  14. Westore 1.0 正式发布 - 小程序框架一个就够
  15. lumen 5.6 设置APP_KEY为32位长的随机字符串
  16. [POJ3378]Crazy Thairs
  17. solr7.4 安装与使用
  18. load file within a jar
  19. Ubantu里面的Sublime Text3不支持中文的解决办法
  20. android中MVP模式(一) - 清风明月的专栏 - CSDN博客

热门文章

  1. ButterKnife注入注解框架用法
  2. Codeforces Good Bye 2018
  3. bzoj 1823: [JSOI2010]满汉全席 &amp;&amp; bzoj 2199 : [Usaco2011 Jan]奶牛议会 2-sat
  4. springcloud的fallback与fallbackFactory
  5. 华为手机不能连接android studio进行调试的解决办法
  6. js原型解释图
  7. 科学计算三维可视化---TraitsUI(控件)
  8. JAVA多线程提高十四: 面试题
  9. jdk源码
  10. ASP.NET对无序列表批量操作的三种方法