题目
解题思路
很容易看出题面给出的是让我们求一遍01背包和完全背包。
但是这肯定会超时:
那么对于01背包,我们用二进制优化
对于完全背包,我们讲完全背包的方程的状态与答案换一下,因为花费最多50000
代码二进制优化01背包+完全背包
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fre(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#define M 210
#define N 110
using namespace std;
int n,m,a[M][N][N],f[M][N],flag;
int main(){
// fre(lines);
scanf("%d%d",&n,&m);
memset(f,125/3,sizeof(f)); flag=f[m][n];
memset(a,125/3,sizeof(a));
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) if (i!=j){
int t,x[21];
scanf("%d",&t);
for (int q=1;q<=t;q++) {
scanf("%d",&x[q]);
if (!x[q]) x[q]=flag;
}
for (int q=1;q<=m;q++) a[q][i][j]=x[(q-1)%t+1];
}
f[0][1]=0;
for (int k=1;k<=m;k++) if (k!=m){
for (int j=1;j<=n;j++)
for (int i=1;i<=n;i++)
if (j!=i) f[k][j]=min(f[k][j],f[k-1][i]+a[k][i][j]);
} else {
int j=n;
for (int i=1;i<=n;i++)
if (j!=i) f[k][j]=min(f[k][j],f[k-1][i]+a[k][i][j]);
}
printf("%d",f[m][n]!=flag?f[m][n]:0);
}