Perform
甚至在打标题的时候还打成了preform
怪不得比赛打preform了
题解:
非常水的一个DP
定义\(i\)为第\(i\)个城市,\(j\)为第\(j\)天,\(l\)为上一天从\(l\)城市到达\(i\)
接着是循环:
第\(j\)天从\(l\)到达\(i\),是通过\(l\)在\(j-1\)天的航班飞过来
显然应当是\((j-1)\bmod sum_l\)
如果\(sum_l\)为\(0\)说明没有这一航班自然就不能转移
状态转移方程:
f[i][j]=min(f[i][j],f[l][j-1]+a[l][i].t[(j-1)%a[l][i].sum+1]);
初值:
\(f[1][0]=0\),其他\(-INF\)
目标:\(f[n][k]\)
然后就是先枚举天数再枚举城市,这样没后效性
数据范围小到暴搜都能过
然后就是注意多测
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n,k,ans=0x3f3f3f3f;
int f[22][2222];
struct node {
int sum;
int t[30];
}a[20][20];
int read(){
int i=1,j=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
i=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
j=j*10+ch-48;
ch=getchar();
}
return i*j;
}
void in(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==i){
continue;
}
a[i][j].sum=read();
for(int k=1;k<=a[i][j].sum;k++){
a[i][j].t[k]=read();
}
}
}
}
void work(){
memset(f,0x3f,sizeof(f));
f[1][0]=0;
for(int j=1;j<=k;j++){
for(int i=1;i<=n;i++){
for(int l=1;l<=n;l++){
if(i==l){
continue;
}
else if(a[l][i].t[(j-1)%a[l][i].sum+1]==0){
continue;
}
else{
f[i][j]=min(f[i][j],f[l][j-1]+a[l][i].t[(j-1)%a[l][i].sum+1]);
}
}
}
}
}
void out(){
ans=f[n][k];
if(ans==0x3f3f3f3f)ans=0;
cout<<ans<<endl;
}
void renew(){
memset(a,0,sizeof(a));
ans=0x3f3f3f3f;
}
int main(){
freopen("perform.in","r",stdin);
freopen("perform.out","w",stdout);
while(scanf("%d%d",&n,&k)!=EOF){
if(n==0&&k==0){
break;
}
in();
work();
out();
renew();
}
return 0;
}

浙公网安备 33010602011771号