#include<
iostream >
#include< cstdio >
using namespace std;
int taosum=0,n,m,tim,tili;
long long int f[1001];
struct Tao{
long long int x,y;
long long int sum,cs;
};
Tao tao[2500001];
int t=0;
void input()
{
int k;
scanf("%d%d%d%d",&n,&m,&tim,&tili);
for(int i=1;i<=n;++i)//x
for(int
j=1;j<=m;++j)//y
{
scanf("%d",&k);
if(k!=0)
{
++t;
tao[t].x=i;
tao[t].y=j;
tao[t].sum=k;
}
}
t=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
scanf("%d",&k);
if(k!=0)
{
t++;
tao[t].cs=k;
}
}
int p=t;
for(int i=1;i<=p;++i)
{
while(tao[i].cs!=1)
{
tao[i].cs--;
t++;
tao[t].x=tao[i].x;
tao[t].y=tao[i].y;
tao[t].sum=tao[i].sum;
}
}
}
int main()
{
input();
for(int i=1;i<=t;++i)
for(int
j=min(tim,tili);j>(tao[i].x+tao[i].y)*2;--j)
f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
printf("%d\n",f[min(tili,tim)]);
return 0;
}
方法二:二进制分法:
#include<
iostream >
#include< cstdio >
using namespace std;
int taosum=0,n,m,tim,tili;
long long int f[200001];
struct Tao{
long long int x,y;
long long int sum;
};
Tao tao[3600010];
int t=0;
void input()
{
int k;
scanf("%d%d%d%d",&n,&m,&tim,&tili);
for(int i=1;i<=n;++i)//x
for(int
j=1;j<=m;++j)//y
{
scanf("%d",&k);
if(k!=0)
{
++t;
tao[t].x=i;
tao[t].y=j;
tao[t].sum=k;
}
}
int p=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
scanf("%d",&k);//ci shu
if(k!=0&&tao[p+1].sum!=0)
{
p++;
for(int i=1;i<=k;i*=2)
{
if(i==1)
{
tao[p].x=tao[p].x*i;
tao[p].y=tao[p].y*i;
tao[p].sum=tao[p].sum*i;
k-=i;
continue;
}
++t;
tao[t].x=tao[p].x*i;
tao[t].y=tao[p].y*i;
tao[t].sum=tao[p].sum*i;
k-=i;
}
if(k>0)
{
++t;
tao[t].x=tao[p].x*k;
tao[t].y=tao[p].y*k;
tao[t].sum=tao[p].sum*k;
}
}
}
}
int main()
{
input();
int VV=min(tim,tili-1);
for(int i=1;i<=t;++i)
for(int
j=VV;j>=(tao[i].x+tao[i].y)*2;--j)
f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
printf("%d\n",f[VV]);
return 0;
}
方法三:没过,不分解,01背包再加一层循环
代码:
#include< iostream >
#include< cstdio >
using namespace std;
int taosum=0,n,m,tim,tili;
long long int f[1001];
struct Tao{
long long int x,y;
long long int sum,cs;
};
Tao tao[3600010];
int t=0;
void input()
{
int k;
scanf("%d%d%d%d",&n,&m,&tim,&tili);
for(int i=1;i<=n;++i)//x
for(int
j=1;j<=m;++j)//y
{
scanf("%d",&k);
if(k!=0)
{
++t;
tao[t].x=i;
tao[t].y=j;
tao[t].sum=k;
}
}
t=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
scanf("%d",&k);
if(k!=0)
{
t++;
tao[t].cs=k;
}
}
}
int main()
{
input();
for(int i=1;i<=t;++i)
for(int
l=1;l<=tao[i].cs;++l)
for(int j=min(tim,tili-1);j>=(tao[i].x+tao[i].y)*2;--j)
f[j]=max(f[j],f[j-2*tao[i].x-2*tao[i].y]+tao[i].sum);
printf("%d\n",f[min(tili-1,tim)]);
return 0;
}
正确代码:
一:
#include <
cstdio >
#include <
iostream >
using namespace
std;
int
V,n,m,T,A,amount[105][105],f[20000],value[105][105];
int main()
{
scanf("%d%d%d%d",&n,&m,&T,&A);
if(T>A-1)V=A-1;
else
V=T;
for(int
i=1;i<=n;i++)
for(int
j=1;j<=m;j++)
scanf("%d",&value[i][j]);
for(int
i=1;i<=n;i++)
for(int
j=1;j<=m;j++)
scanf("%d",&amount[i][j]);
for(int
i=1;i<=n;i++)
for(int
j=1;j<=m;j++)
for(int
k=1;k<=amount[i][j];k++)
for(int
t=V;t>=2*(i+j);t--)
if(f[t]
f[t]=f[t-2*(i+j)]+value[i][j];
printf("%d",f[V]);
return
0;
}
正确二:
#include<
iostream >
#include<
cstdio >
#include<
vector >
using namespace
std;
typedef pair<
int,int > pi;
vectorvec;
int
dp[110],a[110][110];
int main(){
int
m,n;cin>>m>>n;
int V,temp;
cin>>V>>temp;
V=min(V,temp-1);
for(int
i=1;i<=m;i++)
for(int
j=1;j<=n;j++){
cin>>a[i][j];
}
for(int
i=1;i<=m;i++){
for(int
j=1;j<=n;j++){
cin>>temp;
if(temp!=0){
int t=1;
while(temp>t){
vec.push_back(pi(t*a[i][j],2*t*(i+j)));
temp-=t;
t=t<<1;
}
if(temp>0)
vec.push_back(pi(temp*a[i][j],2*temp*(i+j)));
}
}
}
for(int
i=0;i
int
tea=vec[i].first;
int
teb=vec[i].second;
for(int
j=V;j>=teb;j--){
dp[j]=max(dp[j],dp[j-teb]+tea);
}
}
cout<<dp[V];
}