题意:求在一定l时间内看完n中电影中的m是否可能,若可能则最后快乐度是多少。
之前错了好多遍,一直找不到原因,后来在百度上看了很多别人的代码发现只有初始化不同
我的初始化: memset(f,0,sizeof(f));
别人的: for(int i=0;i<=m;i++)
for(int j=0;j<=l;j++) { f[i][j] = -1 ; if(i==0) f[i][j] = 0; }
一开始认为没什么影响,但是苦于一直找不到原因,所以我将自己的初始化改了后,AC了,后来反复思考
终于知道:若所有的f[i][j] = 0 的话,在判断时我不能确定我在看这部电影之前的时间“衔接”的上来,即在l-( j - v)的时间里刚好可以看x部电影。若全部f[i][j] = -1的话,则在判断时后第一次改变值时 f[i][j] = f[i-1][j-v]+w会发生误差(少了1)。
代码:
#include<iostream>
#include<string.h>
#define INF 999999
using namespace std;
long f[110][10101];
int v[110],w[110];
int n,m,l;
void TwoPack(int v,int w)
{
for(int j=l;j>=v;j--)
{
for(int i=1;i<=m;i++)
if(f[i][j]<f[i-1][j-v]+w&&f[i-1][j-v]!=-1) f[i][j]=f[i-1][j-v]+w;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&l);
for(int i=0;i<n;i++) scanf("%d%d",&v[i],&w[i]);
for(int i=0;i<=m;i++)
{
for(int j=0;j<=l;j++)
{
f[i][j]=-1; if(i==0) f[i][j]=0;
}
}
for(int i=0;i<n;i++) TwoPack(v[i],w[i]);
if(f[m][l]!=-1) printf("%ld\n",f[m][l]);
else printf("0\n");
}
return 0;
}