Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_36480062
Algorithm
提交
0e3d2209
A
Algorithm
项目概览
qq_36480062
/
Algorithm
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
Algorithm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
0e3d2209
编写于
1月 11, 2020
作者:
qq_36480062
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
commit
上级
f4580c66
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
170 addition
and
22 deletion
+170
-22
algorithm/com/shiyu/tsdt.java
algorithm/com/shiyu/tsdt.java
+9
-9
algorithm/dp/带权区域调度.java
algorithm/dp/带权区域调度.java
+84
-1
algorithm/greedy/区间覆盖.java
algorithm/greedy/区间覆盖.java
+63
-3
algorithm/greedy/区间选点.java
algorithm/greedy/区间选点.java
+14
-9
未找到文件。
algorithm/com/shiyu/tsdt.java
浏览文件 @
0e3d2209
package
com.shiyu
;
import
java.util.PriorityQueue
;
public
class
tsdt
{
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
isPalindrome
(
121
));
PriorityQueue
<
Integer
>
a
=
new
PriorityQueue
<
Integer
>();
a
.
add
(
6
);
a
.
add
(
5
);
System
.
out
.
println
(
a
.
poll
());
// System.out.println(isPalindrome(121));
// PriorityQueue<Integer> a = new PriorityQueue<Integer>();
//
// a.add(6);
// a.add(5);
//
// System.out.println(a.poll());
int
d
=
2
&
3
;
System
.
out
.
println
(
d
);
}
...
...
algorithm/dp/带权区域调度.java
浏览文件 @
0e3d2209
package
dp
;
import
java.util.*
;
/**
* 带权的区间调度
* 存在单一资源R,有n个需求{1, 2, …, n},每个需求指定一个开始时间bi与一个结束时间ei,在时间区间[bi, ei]内该需求想要占用资源R,资源R一旦被占用则无法被其他需求利用。每个需求i带有一个权值vi,代表该需求被满足之后能够带来的价值或者贡献。如果两个需求的时间区间不重叠,那么它们是相容的。带权值的区间调度问题即,对上面所描述的情境,求出一组相容子集S使得S中的区间权值之和最大。
* <p>
* 解决此类问题一般采用动态规划的思路,执行步骤分以下几个阶段:
* <p>
* 对所有的需求按照结束时间排序。
* 求出所有需求前面所有的需求中和它相容的最后一个需求,记为pi。
* 若只在前i个需求中求相容子集,则可以得到的最大权值之和为M[i],
* 可以推导出:M[i]=max(wi+M[pi],M[i-1]),即如果最大的相容子集中包含需求i,则其权值之和为需求i的权值加上之前所有和它相容的需求子集的最大相容子集的权值之和;若不包含需求i,则其权值之和为前i-1个需求而的最大相容子集的权值之和。而应在其中取最大值,作为M[i]。
* 计算出来所有的M[i]之后,自顶而上,求出所有使权值之和变为最大的需求。
*/
public
class
带权区域调度
{
static
class
Node
implements
Comparator
<
Node
>
{
public
int
start
=
-
1
;
//起点
public
int
end
=
-
1
;
//终点
public
int
weight
=
-
1
;
//权重
public
int
p
=
-
1
;
//求出所有需求前面所有的需求中和它相容的最后一个需求,记为pi
public
Node
(
int
start
,
int
end
,
int
weight
)
{
this
.
start
=
start
;
this
.
end
=
end
;
this
.
weight
=
weight
;
}
@Override
public
int
compare
(
Node
o1
,
Node
o2
)
{
if
(
o1
.
end
==
o2
.
end
)
return
o1
.
start
-
o2
.
start
;
return
o1
.
end
-
o2
.
end
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
Node
node
=
(
Node
)
o
;
return
start
==
node
.
start
&&
end
==
node
.
end
&&
weight
==
node
.
weight
;
}
@Override
public
int
hashCode
()
{
return
start
*
100
+
end
*
10
+
weight
;
}
@Override
public
String
toString
()
{
final
StringBuilder
sb
=
new
StringBuilder
(
"Node{"
);
sb
.
append
(
"start="
).
append
(
start
);
sb
.
append
(
", end="
).
append
(
end
);
sb
.
append
(
", num="
).
append
(
weight
);
sb
.
append
(
'}'
);
return
sb
.
toString
();
}
}
public
static
void
main
(
String
[]
args
)
{
}
public
static
void
ComputeP
(
ArrayList
<
Node
>
nodes
)
{
Collections
.
sort
(
nodes
,
new
Comparator
<
Node
>()
{
@Override
public
int
compare
(
Node
o1
,
Node
o2
)
{
if
(
o1
.
end
==
o2
.
end
)
return
o1
.
start
-
o2
.
start
;
return
o1
.
end
-
o2
.
end
;
}
});
for
(
int
i
=
0
;
i
<
nodes
.
size
();
i
++)
{
for
(
Node
node
:
nodes
)
{
if
(
node
.
start
>=
nodes
.
get
(
i
).
end
)
node
.
p
=
i
;
}
}
int
[]
temp
=
new
int
[
nodes
.
size
()];
Arrays
.
fill
(
temp
,
-
1
);
}
}
}
\ No newline at end of file
algorithm/greedy/区间覆盖.java
浏览文件 @
0e3d2209
package
greedy
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
/**
* 有n头牛,它们都有一个工作时间的区间s至e,
* 给定一个总的工作时间t,
* 问最少需要多少头牛才能覆盖从1到t的工作时间
* <p>
* 题目说人话就是:比如1点到10点需要有牛耕地,会给出,几点到几点需要工作
* 有的牛只在3点到4点工作,会给出每头牛在什么时间会工作
* 问最少需要多少头牛,才能在1-10点都有牛工作
*/
public
class
区间覆盖
{
static
class
Node
{
public
int
start
;
public
int
start
=
-
1
;
public
int
end
=
-
1
;
public
Node
(
int
start
)
{
...
...
@@ -55,10 +68,57 @@ public class 区间覆盖 {
}
public
static
void
main
(
String
[]
args
)
{
ArrayList
<
Node
>
list
=
new
ArrayList
<
Node
>();
list
.
add
(
new
Node
(
1
,
7
));
list
.
add
(
new
Node
(
3
,
6
));
list
.
add
(
new
Node
(
6
,
10
));
F
(
list
,
list
.
size
(),
0
,
10
);
}
public
static
void
F
()
{
/**
* @param list 区间对象
* @param N 区间数量
* @param begin 需要覆盖的区间开头,
* @param last 需要覆盖的区间结尾
*/
public
static
void
F
(
ArrayList
<
Node
>
list
,
int
N
,
int
begin
,
int
last
)
{
Collections
.
sort
(
list
,
new
Comparator
<
Node
>()
{
@Override
public
int
compare
(
Node
o1
,
Node
o2
)
{
if
(
o1
.
start
==
o2
.
start
)
return
o1
.
end
-
o2
.
end
;
return
o1
.
start
-
o2
.
start
;
}
});
//按照区间左边界升序排列
int
start
=
begin
;
//要覆盖的目标点
int
end
=
1
;
int
ans
=
1
;
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
int
s
=
list
.
get
(
i
).
start
;
int
e
=
list
.
get
(
i
).
end
;
if
(
i
==
0
&&
s
>
begin
)
break
;
//由于待选区间已经按开始时间排了序,
// 如果第一个找不到需要被覆盖的区间左边界,则无解
if
(
s
<=
start
)
{
end
=
Math
.
max
(
e
,
end
);
}
else
{
//开始下一个区间,超过end
ans
++;
//上一个目标覆盖达成
start
=
end
+
1
;
if
(
s
<=
start
)
{
end
=
Math
.
max
(
end
,
e
);
}
else
{
break
;
//无法完全覆盖给定的区间,无解
}
}
if
(
end
>=
last
)
{
break
;
//如果找出来一个区间,可以覆盖区间的全部,那么就够了,不需要找了
}
}
if
(
end
<
last
)
{
System
.
out
.
println
(-
1
);
}
else
{
System
.
out
.
println
(
ans
);
}
}
}
algorithm/greedy/区间选点.java
浏览文件 @
0e3d2209
...
...
@@ -23,7 +23,9 @@ import java.util.Comparator;
* 还有所有 0<i<=max_v的值构成的 i到i-1的长0的边和 i-1到i的长1的边.所以这样我们就形成了一个具有点[0,max_v]的有向图.在原图处理时,为了避免ai-1==-1,我们令所有ai与bi都自增了10.所以我们形成了一个具有点[9,max_v]的有向图(其实就是差分约束系统).我们的目标是令S[max_v]-S[9]的值最小.(切记这里不是仅使S[max_v]的值最小,因为我们这里只有从9 ,10,11,…max_v 的值构成了一个差分约束系统.max_v的值和0号点的值是不在一个系统的. 0号点是超级源点,它的值与系统中其他点的值是无关的.)
* 然后我们上面已经知道了希望让系统中S[max_v]和S[9]的值差距尽量小.(构成差分约束系统时,1.如果在所有点外添加一个超级源0号点,并使得超级源到所有其他点的距离为0,那么最终求出的0号点到其他所有原始点的最短距离就是本系统的一个可行解,且可行解之间的差距最小. 2.如果初始时不添加超级源,只是将原始点的初始距离设为INF,且令其中一个原始点的初始距离为0,然后求该点到其他所有点的最短距离,那么最短距离的集合就是一个可行解,且该可行解两两之间的差距最大.注意方案2只能在该问题一定存在解的时候即肯定不存在负权环的时候用.否则从1号点到其他点没有路,但是其他点的强连通分量中有负权环,这样根本探测不到错误) 所以我们需要采取方案1.
* 转自大佬:
* 贪心策略
* 贪心策略,尽量先选区间右边的点
* 还有树状数组
* 拆分约束
*/
public
class
区间选点
{
static
class
Node
{
...
...
@@ -75,6 +77,8 @@ public class 区间选点 {
}
/**
* 贪心策略实现
*
* @param n 区间数量
* @param list 区间对象
*/
...
...
@@ -94,24 +98,25 @@ public class 区间选点 {
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
int
start
=
list
.
get
(
i
).
start
;
int
end
=
list
.
get
(
i
).
end
;
int
cnt
=
sum
(
axis
,
start
,
end
);
list
.
get
(
i
).
num
-=
cnt
;
int
cnt
=
sum
(
axis
,
start
,
end
);
//查询数轴上(数组start到end)这个范围已经存在的点,
list
.
get
(
i
).
num
-=
cnt
;
//当前该区间需要多少个点(去掉已经,已经包含数量的点)
while
(
list
.
get
(
i
).
num
>
0
)
{
if
(
axis
[
end
]
==
0
)
{
axis
[
end
]
=
1
;
list
.
get
(
i
).
num
--;
end
--;
if
(
axis
[
end
]
==
0
)
{
//如果该区间右边界如果未被标记
axis
[
end
]
=
1
;
//标记区间右边界
list
.
get
(
i
).
num
--;
//维护该区间需要的点
end
--;
//维护end,右边界左移一位
}
else
{
end
--;
end
--;
//右边界左移一位
}
}
}
System
.
out
.
println
(
sum
(
axis
,
0
,
max
));
return
sum
(
axis
,
0
,
max
);
return
sum
(
axis
,
0
,
max
);
//整个数轴上有几个点
}
/**
* 统计数轴axis上s-t区间已经有多少个点被选中
* 贪心策略辅助统计方法
*
* @param axis 数轴
* @param s 区间左边界
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录