2.7
1.蓝桥王国(dijkstra)
2.吃奶酪
3.榨取kkksc03
4.补给
dijkstra板子题,主要是运用优先队列完成
#include
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
const int INF=0x3f3f3f3f3f3f3f3fLL;
const int N=3e5+5;;
struct edge{
int from,to,w;
edge(int a,int b,int c){
from=a;
to=b;
w=c;
}
}; //这个主要是保存图中每个节点的邻居节点
vectore[N];
struct s_node{
int id,n_dis; //输入优先队列的成员
s_node(int a,int b){
id=a;
n_dis=b;
}
bool operator < (const s_node & a)const { //用重载运算符,这个是结构体的写法
return n_dis>a.n_dis;
}
};
int n,m;
int pre[N]; //主要用于记录前驱节点,帮助记录路径
void print_path(int s,int t) //输出从s到t之间的最短路径
{
if (s==t){
cout<<0;
return ;
}
print_path(s,pre[t]);
cout<Q; //建立优先数组,存储节点信息
Q.push(s_node(s,dis[s])); //放第一个节点
while (!Q.empty()){
s_node q=Q.top(); Q.pop(); //输出第一个节点
if (done[q.id]) continue; //如果已经找到了最短路径,那么就没必要继续找了,就直接退出
done[q.id]=true;
//开始检查q节点的邻居节点
for (int i=0;i y.w+q.n_dis){
dis[y.to]=y.w+q.n_dis;
Q.push(s_node(y.to,dis[y.to]));
pre[y.to]=q.id;
}
}
}
}
signed main(){
cin>>n>>m;
for (int i=1;i<=n;++i) e[i].clear();
while (m--){
int u,v,w;
cin>>u>>v>>w;
e[u].push_back(edge(u,v,w));
}
dijkstra();
for (int i=1;i<=n;++i){
if (dis[i]>=INF) cout<<-1<<" ";
else cout<
第一行三个整数 �,�,�n,M,T,表示一共有 �n(1≤�≤1001≤n≤100)个愿望, kkksc03 的手上还剩 �M(0≤�≤2000≤M≤200)元,他的暑假有 �T(0≤�≤2000≤T≤200)分钟时间。
第 22~�+1n+1 行 ��mi , ��ti 表示第 �i 个愿望所需要的金钱和时间。
一行,一个数,表示 kkksc03 最多可以实现愿望的个数。
思路:01背包问题,就是由两个背包容量
#include
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
const int N=1e5+5;
int dp[205][205],n,m,t,qian[205],tt[205];
signed main() {
cin>>n>>m>>t;
for (int i=1;i<=n;++i){
cin>>qian[i]>>tt[i];
}
memset(dp,0,sizeof(dp));
for (int k=1;k<=n;++k){
for (int i=m;i>=qian[k];--i){
for (int j=t;j>=tt[k];--j){
dp[i][j]=max(dp[i][j],dp[i-qian[k]][j-tt[k]]+1);
}
}
}
cout<
房间里放着 �n 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0)(0,0) 点处。
第一行有一个整数,表示奶酪的数量 �n。
第 22 到第 (�+1)(n+1) 行,每行两个实数,第 (�+1)(i+1) 行的实数分别表示第 �i 块奶酪的横纵坐标 ��,��xi,yi。
输出一行一个实数,表示要跑的最少距离,保留 22 位小数。
输入 #1复制
4 1 1 1 -1 -1 1 -1 -1
输出 #1复制
7.41
对于全部的测试点,保证 1≤�≤151≤n≤15,∣��∣,∣��∣≤200∣xi∣,∣yi∣≤200,小数点后最多有 33 位数字。
对于两个点 (�1,�1)(x1,y1),(�2,�2)(x2,y2),两点之间的距离公式为 (�1−�2)2+(�1−�2)2(x1−x2)2+(y1−y2)2。
思路:状态压缩DP
#include
using namespace std;
#define lowbit(x) (x& - (x))
const int INF=0x3f3f3f3f3f3f3f3fLL;
#define int long long
double dp[1<<16][20];
double a[20][20];
double x[20],y[20];
int n;
double dis(int i,int j){
return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
signed main(){
cin>>n;
memset(dp,127,sizeof(dp));
for (int i=1;i<=n;++i){
cin>>x[i]>>y[i];
dp[1<<(i-1)][i]=dis(i,0);
}
x[0]=0,y[0]=0;
for (int i=0;i
小蓝是一个直升飞机驾驶员,他负责给山区的 �n 个村庄运送物资。
每个月,他都要到每个村庄至少一次,可以多于一次,将村庄需要的物资运送过去。
每个村庄都正好有一个直升机场,每两个村庄之间的路程都正好是村庄之间的直线距离。
由于直升机的油箱大小有限,小蓝单次飞行的距离不能超过 �D。每个直升机场都有加油站,可以给直升机加满油。
每个月,小蓝都是从总部出发,给各个村庄运送完物资后回到总部。如果方便,小蓝中途也可以经过总部来加油。
总部位于编号为 11 的村庄。
请问,要完成一个月的任务,小蓝至少要飞行多长距离?
输入的第一行包含两个整数 �n,�D,分别表示村庄的数量和单次飞行的距离。
接下来 �n 行描述村庄的位置,其中第 �i 行两个整数 ��xi,��yi 分别表示编号为 �i 的村庄的坐标。村庄 �i 和村庄 �j 之间的距离为 (��−��)2+(��−��)2(xi−xj)2+(yi−yj)2。
输出一行,包含一个实数,四舍五入保留正好 22 位小数,表示答案。
输入 #1复制
4 6 1 1 4 5 8 5 11 1
输出 #1复制
28.00
对于所有数据,保证,1≤�≤20,1≤��,��≤104,1≤�≤1051≤n≤20,1≤xi,yi≤104,1≤D≤105。
思路:floyd找到最短路径,然后状压DP
#include
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
const int N=1e5+5;
double dp[1<<20][25],a[25][25];
int n,d;
double x[21],y[21];
double dis(int i,int j){
return sqrt(((x[i]-x[j])*(x[i]-x[j]))+((y[i]-y[j])*(y[i]-y[j])));
}
void floyd(){
for (int k=1;k<=n;++k){
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}
}
}
}
signed main() {
cin>>n>>d;
for (int i=1;i<=n;++i){
cin>>x[i]>>y[i];
}
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
if (dis(i,j)>d){
a[i][j]=1e10;
}
else {
a[i][j]=dis(i,j);
}
}
}
floyd();
for(int i=0;i<(1<