1.CF2B(字典序输出 10的判断)
1.dfs与bfs有2的1000次方种选择 时间一定会爆
2.dp的模板 (1)单调 (2)无后效性 (3)在前面两个中选择
3.如果对于搜索进行最优剪枝,也可也变成dp 但是为何不直接用dp?dp之所以快于搜索,因为搜索会进行根本到不了结果的道路。
4.为什么是min(2,5)因为答案的后导零一定是由2*5组成。那么min(2,5)一定对映着答案零的个数
#include<cstdio>
#include<algorithm>
using namespace std;
const int Inf=0x7FFFFFFF;//七个F代表最大
int n,t,num[1002][1002][2],f[1002][1002][2];
void Print(int i,int j,int k) {//k=0代表R k=1代表D
if(i==1&&j==1) { //递归输出函数
putchar(k? 'D':'R');
return ; //边界
}
if(i==1)
Print(i,j-1,0);
else if(j==1)
Print(i-1,j,1);
else if(f[i][j][t]==f[i][j-1][t]+num[i][j][t])
Print(i,j-1,0);
else
Print(i-1,j,1);
if(i!=n||j!=n)
putchar(k? 'D':'R'); //在(n,n)处不输出
}
int main() {
int ans;
scanf("%d",&n);
for(int i=1,k;i<=n;++i)
for(int j=1;j<=n;++j) { //预处理因子个数
scanf("%d",&k);
if(!k) {
num[i][j][0]=num[i][j][1]=1;
t=i; //特判0,记录位置
}
else {
for(;!(k%2);k/=2)
++num[i][j][0];
for(;!(k%5);k/=5)
++num[i][j][1];
}
}
for(int i=1;i<=n;++i)
f[0][i][0]=f[i][0][0]=f[0][i][1]=f[i][0][1]=Inf; //由于转移方程使用min,将边界赋为最大值
f[1][1][0]=num[1][1][0];
f[1][1][1]=num[1][1][1];
for(int k=0;k<2;++k)
for(int i=1;i<=n;++i)
for(int j=i==1? 2:1;j<=n;++j)
f[i][j][k]=min(f[i][j-1][k],f[i-1][j][k])+num[i][j][k];
ans=min(f[n][n][0],f[n][n][1]);
if(t&&ans>1) { //情况2 按照字典序输出 先下后右再下一定经过0
printf("1\n");
for(int i=1;i<t;++i)
putchar('D');
for(int i=1;i<n;++i)
putchar('R');
for(int i=t;i<n;++i)
putchar('D');
}
else { //情况1
printf("%d\n",ans);
t=!(f[n][n][0]<f[n][n][1]);
Print(n,n,0);//递归输出字典序
}
return 0;
}
2. p1027 (floyd 矩形 距离)
1.两点之间最短距离(带权值)
2.数组处理城市 用一维数组解决
3.Floyd n的三次方时间
4.待处理 结构体存储节点 使用spfa dijkstra
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;
int n,s,tt,a,b;
double x[101][5],dis[601][601],y[101][5],t[101];
double gd(double xa,double ya,double xb,double yb)//距离公式
{
return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
}
int id(int i,int j)//城市中飞机站的id
{
return (i-1)*4+j;
}
int main()
{
scanf("%d",&n);
for(int T=1;T<=n;T++)
{
double ans=2147483647;
for(int i=1;i<=101;i++)
{
for(int j=1;j<=101;j++)
{
dis[i][j]=2147483647;
}
}
scanf("%d%d%d%d",&s,&tt,&a,&b);
for(int i=1;i<=s;i++)
{
for(int j=1;j<=3;j++)
{
scanf("%lf",&x[i][j]);
scanf("%lf",&y[i][j]);
}
double da=gd(x[i][1],y[i][1],x[i][2],y[i][2]);
double db=gd(x[i][1],y[i][1],x[i][3],y[i][3]);
double dc=gd(x[i][2],y[i][2],x[i][3],y[i][3]);
double maxn=0;
if(da>db&&da>dc)
x[i][4]=x[i][1]+x[i][2]-x[i][3],
y[i][4]=y[i][1]+y[i][2]-y[i][3];
if(db>da&&db>dc)
x[i][4]=x[i][1]+x[i][3]-x[i][2],
y[i][4]=y[i][1]+y[i][3]-y[i][2];
if(dc>da&&dc>db)
x[i][4]=x[i][2]+x[i][3]-x[i][1],
y[i][4]=y[i][2]+y[i][3]-y[i][1];
scanf("%lf",&t[i]);
}//算出每个城市的坐标
/* for(int i=1;i<=s;i++)
{
for(int j=1;j<=4;j++)
{
printf("%d,%d:(%.0lf,%.0lf)",i,j,x[i][j],y[i][j]);
}
printf("\n");
}*/
for(int i=1;i<=s;i++)
{
for(int j=1;j<=4;j++)
{
for(int k=1;k<=4;k++)
{
if(j==k)continue;
double d=gd(x[i][j],y[i][j],x[i][k],y[i][k]);
dis[id(i,j)][id(i,k)]=d*t[i];
}
}
}//每个城市中机场的距离费用
for(int i=1;i<=s;i++)
{
for(int j=1;j<=4;j++)
{
for(int k=1;k<=s;k++)
{
if(i==k)continue;
for(int l=1;l<=4;l++)
{
double d=gd(x[i][j],y[i][j],x[k][l],y[k][l]);
dis[id(i,j)][id(k,l)]=d*tt;
}
}
}
}//不同城市被中机场之间的费用
for(int i=1;i<=s*4;i++)dis[i][i]=0;
for(int k=1;k<=s*4;k++)
{
for(int i=1;i<=s*4;i++)
{
for(int j=1;j<=s*4;j++)
{
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
/* for(int i=1;i<=4*s;i++)
{
for(int j=1;j<=4*s;j++)
{
printf("%d~%d:%.1lf\n",i,j,dis[i][j]);
}
}*/
for(int i=4*(a-1)+1;i<=4*a;i++)
{
for(int j=4*(b-1)+1;j<=4*b;j++)
{
ans=min(ans,dis[i][j]);
}
}//城市a 到 b 的最短路
printf("%.1lf\n",ans);
}
}