B 二维最短路
鱼贩想把货物从港口带到市场。在他的路线上,他必须穿越许多小城市国家的地区。当然,他必须在每个边界付出代价。
因为他是一个好生意人,所以他想选择这样的路线,以便尽可能少付一点钱。另一方面,他必须在一定的时间内上市,否则他的鱼开始闻起来。
输入
第一行包含状态数n和可用时间t。第一个国家是港口,最后一个国家是市场。在这条线之后有n行,每行n个数字,为每个状态指定到第i个状态的行程时间。该表以空行结束。收费表的格式如下。
n至少为3,最多为50.可用的时间少于1000.所有的数字都是整数。
有很多测试用例由空行分隔。输入终止状态数量和时间等于0 0。
产量
对于每个测试案例,您的程序应该在一行上打印总收费量,然后是实际的行程时间。
例
示例输入:
4 7
0 5 2 3
5 0 2 3
3 1 0 2
3 3 2 0
0 2 2 7
2 0 1 2
2 2 0 5
7 2 5 0
0 0
示例输出:
6 6
求在规定时间内花费最少的路径
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn= 2002;
const int inf = 0x3f3f3f3f;
int tu[maxn][maxn],cost[maxn][maxn];
int cnt,t,n;
int head[maxn*maxn];
int vis[maxn][maxn];
int dis[maxn][maxn];
typedef pair<int,int >ppi;
struct node
{
int u,v;
int w,cost;
int next;
} edge[maxn*maxn];
void addedge(int u,int v,int w,int cost)
{
edge[cnt].u = u;
edge[cnt].v= v;
edge[cnt].w = w;
edge[cnt].cost = cost;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void spfa(int s,int e)
{
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
dis[1][0] = 0;
queue<ppi>o;
o.push(make_pair(1,0));
while(!o.empty())
{
ppi uu = o.front();
int u = uu.first;//路径长度
int time = uu.second;//路径花费
vis[u][time] = 0;
o.pop();
for(int i=head[u]; i!=-1; i =edge[i].next)
{
node tmp = edge[i];
int yy = time+tmp.w;
if(yy>t)continue;
if(dis[tmp.v][yy]>dis[tmp.u][time]+tmp.cost)
{
dis[tmp.v][yy]=dis[tmp.u][time]+tmp.cost;
if(!vis[tmp.v][yy])
{
vis[tmp.v][yy] = true;
o.push(make_pair(tmp.v,yy));
}
}
}
}
}
int main()
{
while(cin>>n>>t)
{
cnt = 0;
memset(head,-1,sizeof(head));
if(n==0&&t==0)
break;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d",&tu[i][j]);
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d",&cost[i][j]);
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(i!=j)
addedge(i,j,tu[i][j],cost[i][j]);
}
}
spfa(1,n);
int ans1 = 0x3f3f3f3f,ans2 ;
for(int i=0; i<=t; i++)
{
if(ans1>dis[n][i])
{
ans1 = dis[n][i];
ans2 = i;
}
}
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}
D:
dp[i][j]: 放了第i个巧克力时共有j个盒子中有巧克力的概率..
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
int cases = 1;
while(cin>>n)
{
double p[200][200]= {0};
if(n==-1)break;
cin>>m;
p[1][1]= 1;
//将1个巧克力放在1个盒子中的概率为1
for(int i=2; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
p[i][j] = p[i-1][j]*(j*1.0)/m+p[i-1][j-1]*(m-j+1.0)*1.0/m;
// cout<<p[i][j]<<" "<<endl;
}
}
printf("Case %d: ",cases++);
//cout<<setprecision(7)<<(1.0-p[n][m])<<endl;
printf("%.7f\n",1.0-p[n][m]);
}
}
* dp[i-1][j]*j/m: 在放第i个巧克力的时候,已经有j个盒子中有巧克力了,所以第i个巧克力需要放在已经有巧克力的盒子中
* dp[i-1][j-1]*(m-j+1)/m: 在放第i个巧克力的时候,只有j个盒子中有巧克力。这是第i个巧克力需要放在没有巧克力的盒子中才能使有巧克力的盒子数达到j个