Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_36480062
Algorithm
提交
f4580c66
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 搜索 >>
提交
f4580c66
编写于
1月 10, 2020
作者:
qq_36480062
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
commit
上级
469e7ceb
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
195 addition
and
12 deletion
+195
-12
algorithm/greedy/区间覆盖.java
algorithm/greedy/区间覆盖.java
+64
-0
algorithm/greedy/区间选点.java
algorithm/greedy/区间选点.java
+122
-5
algorithm/greedy/字典序最小.java
algorithm/greedy/字典序最小.java
+9
-7
未找到文件。
algorithm/greedy/区间覆盖.java
0 → 100644
浏览文件 @
f4580c66
package
greedy
;
public
class
区间覆盖
{
static
class
Node
{
public
int
start
;
public
int
end
=
-
1
;
public
Node
(
int
start
)
{
this
.
start
=
start
;
}
public
int
getStart
()
{
return
start
;
}
public
Node
(
int
start
,
int
end
)
{
this
.
start
=
start
;
this
.
end
=
end
;
}
public
void
setStart
(
int
start
)
{
this
.
start
=
start
;
}
public
int
getEnd
()
{
return
end
;
}
public
void
setEnd
(
int
end
)
{
this
.
end
=
end
;
}
@Override
public
int
hashCode
()
{
return
start
*
100
+
end
*
10
;
}
@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
;
}
@Override
public
String
toString
()
{
return
"Node{"
+
"start="
+
start
+
", end="
+
end
+
'}'
;
}
}
public
static
void
main
(
String
[]
args
)
{
}
public
static
void
F
()
{
}
}
algorithm/greedy/区间选点.java
浏览文件 @
f4580c66
package
greedy
;
import
java.util.Scanner
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
/**
* https://blog.csdn.net/u013480600/article/details/37922977
* https://blog.csdn.net/qq_43464645/article/details/95963425
* 有n个区间,最少有多少个点,命中所有区间
* 题意:有n个如下形式的条件:
* ai bi ci,表示在区间[ai, bi]内至少要选择ci个整数点.
* 问你满足n个条件的情况下,最少需要选多少个点?
* 分析:
* 令s[x]表示从区间[0,x]中选择的整数点个数.那么对于条件[ai, bi]选数>=ci个,就是 s[bi]-s[ai-1]>=ci. 即s[ai-1]<=s[bi]+ (-ci)
* 假设有下面两个条件:
* 1 2 3 5 6 3, 那么我们自然得出了s[2]-s[0]>=3 且s[6]-s[4]>=3.
* 如果s[2]=3,s[0]=0,s[6]=3,s[4]=0 是满足上面不等式的.但是其实是不合题意的.因为s[4]必然要>=s[2]和s[0]的.所以我们需要把s的相对值也联系起来.
* 这样就需要添加下面的边. 假设我们令输入读取的区间最大值为max_v. 那么对于所有 0<i<=max_v的值来说,有
* 0<=s[i]-s[i-1]<=1 .转换一下即是: s[i]<=1+s[i-1] && s[i-1]<=0+s[i].
* 根据上面的分析,我们要建的有向图是一个具有max_v+1个点的图.其中的边有:
* n条s[bi]-s[ai-1]>=ci条件构成的从bi到 (ai-1)的长-ci的边.
* 还有所有 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
{
public
int
start
;
public
int
end
=
-
1
;
public
int
num
;
public
Node
(
int
start
,
int
end
,
int
num
)
{
this
.
start
=
start
;
this
.
end
=
end
;
this
.
num
=
num
;
}
@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
&&
num
==
node
.
num
;
}
@Override
public
int
hashCode
()
{
return
start
*
100
+
end
*
10
+
num
;
}
@Override
public
String
toString
()
{
final
StringBuilder
sb
=
new
StringBuilder
(
"Node{"
);
sb
.
append
(
"start="
).
append
(
start
);
sb
.
append
(
", end="
).
append
(
end
);
sb
.
append
(
", num="
).
append
(
num
);
sb
.
append
(
'}'
);
return
sb
.
toString
();
}
}
public
static
void
main
(
String
[]
args
)
{
ArrayList
<
Node
>
list
=
new
ArrayList
<
Node
>();
list
.
add
(
new
Node
(
3
,
7
,
3
));
list
.
add
(
new
Node
(
8
,
10
,
3
));
list
.
add
(
new
Node
(
6
,
8
,
1
));
list
.
add
(
new
Node
(
1
,
3
,
1
));
list
.
add
(
new
Node
(
10
,
11
,
1
));
Q
(
list
.
size
(),
list
);
}
public
static
void
Q
()
{
Scanner
sc
=
new
Scanner
(
System
.
in
);
int
n
=
sc
.
nextInt
();
//区间数量
/**
* @param n 区间数量
* @param list 区间对象
*/
public
static
int
Q
(
int
n
,
ArrayList
<
Node
>
list
)
{
Collections
.
sort
(
list
,
new
Comparator
<
Node
>()
{
@Override
public
int
compare
(
Node
o1
,
Node
o2
)
{
if
(
o1
.
end
==
o2
.
end
)
return
o1
.
start
-
o2
.
start
;
else
return
o1
.
end
-
o2
.
end
;
}
});
int
max
=
list
.
get
(
list
.
size
()
-
1
).
end
;
//右端最大值,区间最右边到哪
int
[]
axis
=
new
int
[
max
+
1
];
//标记数轴上的点是否已经被选中
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
;
while
(
list
.
get
(
i
).
num
>
0
)
{
if
(
axis
[
end
]
==
0
)
{
axis
[
end
]
=
1
;
list
.
get
(
i
).
num
--;
end
--;
}
else
{
end
--;
}
}
}
System
.
out
.
println
(
sum
(
axis
,
0
,
max
));
return
sum
(
axis
,
0
,
max
);
}
/**
* 统计数轴axis上s-t区间已经有多少个点被选中
*
* @param axis 数轴
* @param s 区间左边界
* @param t 区间右边界
* @return 有多少个点
*/
public
static
int
sum
(
int
[]
axis
,
int
s
,
int
t
)
{
int
sum
=
0
;
for
(
int
i
=
s
;
i
<
t
;
i
++)
{
sum
+=
axis
[
i
];
}
return
sum
;
}
public
static
void
updateSums
(
int
t
,
int
[]
sums
)
{
for
(
int
i
=
t
;
i
<
sums
.
length
;
i
++)
{
sums
[
i
]++;
}
}
}
}
\ No newline at end of file
algorithm/greedy/字典序最小.java
浏览文件 @
f4580c66
...
...
@@ -31,18 +31,19 @@ package greedy;
*/
public
class
字典序最小
{
public
static
void
main
(
String
[]
args
)
{
Z
(
6
,
"ACDBCB"
);
String
ab
=
"ACDBCB"
;
Z
(
ab
.
length
(),
ab
);
}
public
static
void
Z
(
int
n
,
String
s
)
{
public
static
String
Z
(
int
n
,
String
s
)
{
String
Cp
=
new
StringBuilder
(
s
).
reverse
().
toString
();
int
p1
=
0
;
int
p2
=
0
;
int
Strlen
=
0
;
int
p1
=
0
;
//源串的开头
int
p2
=
0
;
//翻转过后的源串开头
int
Strlen
=
0
;
//合成的T串长度
StringBuilder
result
=
new
StringBuilder
();
while
(
Strlen
<
n
)
{
if
(
s
.
substring
(
p1
,
s
.
length
()
).
compareTo
(
Cp
.
substring
(
p2
,
Cp
.
length
()
))
>
0
)
{
if
(
s
.
substring
(
p1
).
compareTo
(
Cp
.
substring
(
p2
))
>
0
)
{
Strlen
++;
result
.
append
(
Cp
.
charAt
(
p2
));
p2
++;
...
...
@@ -53,5 +54,6 @@ public class 字典序最小 {
}
}
System
.
out
.
println
(
result
);
return
result
.
toString
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录