2001提高
A.一元三次方程求解(枚举+二分答案) 水题写挂orz
B.数的划分(dfs/dp)这递推我哪会啊。。。
C.统计单词个数(字符串+暴力+区间dp)这题我哪读得懂啊。。。
D.Car的旅行路线(建图spfa)
A
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define eps 1e-4
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
double a,b,c,d,ans[4];
int num=0;
double cal(double x){return x*x*x*a+x*x*b+x*c+d;}
double calc(int x){
double l=x,r=x+1;
while(r-l>=eps){
double mid=(l+r)/2;
if(cal(mid)*cal(x)>0) l=mid;else r=mid;
}return l;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for(int x=-100;x<=99;++x){
if(abs(cal(x))<eps){ans[++num]=x;continue;}
if(abs(cal(x+1))<eps) continue;
if(cal(x)*cal(x+1)<0) ans[++num]=calc(x);
}printf("%.2lf %.2lf %.2lf\n",ans[1],ans[2],ans[3]);
return 0;
}
B
#include<cstdio>
int n,k,sum=0;
void work(int x,int kk,int nn){// x--枚举的数,kk--份数,nn--剩下的数.
if(kk==k) sum++;
else for(int i=x;i<=nn/(k-kk+1);++i) work(i,kk+1,nn-i);
//i<=nn/(k-kk+1)使答案非降序排列,避免重复
}
int main(){
scanf("%d%d",&n,&k);
work(1,1,n);
printf("%d",sum);
return 0;
}
或者
根据有没有大小为1的数转移。
dp[n][k]=dp[n-1][k-1]+dp[n-k][k]
C
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 210
#define inf 0x3f3f3f3f
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,kk,m,w[N][N],dp[N][50],len[7];
char s[N],a[7][N];
bool jud(int l,int r){
for(int i=1;i<=m;++i){
if(len[i]>r-l+1) continue;
bool flag=1;
for(int j=1;j<=len[i];++j)
if(s[l+j-1]!=a[i][j]){flag=0;break;}
if(flag) return 1;
}return 0;
}
int main(){
// freopen("a.in","r",stdin);
n=read();kk=read();
for(int i=1;i<=n;++i) scanf("%s",s+1+(i-1)*20);n*=20;
m=read();for(int i=1;i<=m;++i) scanf("%s",a[i]+1),len[i]=strlen(a[i]+1);
for(int j=1;j<=n;++j)
for(int i=j;i>=1;--i)
w[i][j]=w[i+1][j]+jud(i,j);
for(int i=1;i<=n;++i) dp[i][1]=w[1][i];
for(int k=2;k<=kk;++k)
for(int i=k;i<=n;++i)
for(int j=k-1;j<i;++j)
dp[i][k]=max(dp[i][k],dp[j][k-1]+w[j+1][i]);
printf("%d\n",dp[n][kk]);
return 0;
}
D
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 110
#define inf 0x3f3f3f3f
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int tst,n,wa,h[N<<2],num=0;
double dis[N<<2];
bool inq[N<<2];
struct point{
int x,y;
}a[N][5];
struct edge{
int to,next;double val;
}data[400000];
inline void add(int x,int y,double val){
data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;
data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val;
}
inline int d(point x,point y){return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);}
void spfa(int s){
queue<int>q;memset(dis,127,sizeof(dis));memset(inq,0,sizeof(inq));
for(int i=1;i<=4;++i) q.push((s-1<<2)+i),inq[(s-1<<2)+i]=1,dis[(s-1<<2)+i]=0;
while(!q.empty()){
int x=q.front();q.pop();inq[x]=0;
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;
if(dis[y]>dis[x]+data[i].val){
dis[y]=dis[x]+data[i].val;
if(!inq[y]) q.push(y),inq[y]=1;
}
}
}
}
int main(){
// freopen("a.in","r",stdin);
tst=read();
while(tst--){
n=read();wa=read();int s=read(),t=read();num=0;
memset(h,0,sizeof(h));
for(int i=1;i<=n;++i){
for(int j=1;j<=3;++j) a[i][j].x=read(),a[i][j].y=read();
int v=read(),l1=d(a[i][1],a[i][2]);
int l2=d(a[i][1],a[i][3]),l3=d(a[i][2],a[i][3]);
if(l1>l2&&l1>l3) a[i][4].x=a[i][1].x+a[i][2].x-a[i][3].x,a[i][4].y=a[i][1].y+a[i][2].y-a[i][3].y;
else if(l2>l1&&l2>l3) a[i][4].x=a[i][1].x+a[i][3].x-a[i][2].x,a[i][4].y=a[i][1].y+a[i][3].y-a[i][2].y;
else a[i][4].x=a[i][3].x+a[i][2].x-a[i][1].x,a[i][4].y=a[i][3].y+a[i][2].y-a[i][1].y;
add((i-1)*4+1,(i-1)*4+2,sqrt(l1)*v);add((i-1)*4+1,(i-1)*4+3,sqrt(l2)*v);
add((i-1)*4+3,(i-1)*4+2,sqrt(l3)*v);
for(int j=1;j<=3;++j) add(i*4,(i-1)*4+j,sqrt(d(a[i][4],a[i][j]))*v);
for(int j=1;j<i;++j)
for(int ii=1;ii<=4;++ii)
for(int jj=1;jj<=4;++jj)
add((i-1<<2)+ii,(j-1<<2)+jj,sqrt(d(a[i][ii],a[j][jj]))*wa);
}double ans=inf;spfa(s);for(int i=1;i<=4;++i) ans=min(ans,dis[(t-1<<2)+i]);
printf("%.1f",ans);
}return 0;
}