第一组dp解题报告
t1
一开始还被这个给搞到了,突然发现问题和图片是不一样的(
这个的特点就在于每一个物品的贡献都是没有先后的,也就是说我可以把每一个物品都当作最后一个来消除影响
所以代码也很简单
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
long long v[2010];
long long f[2010],g[2010];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
}
f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=m;j>=v[i];j--) f[j]+=f[j-v[i]],f[j]%=10;
}
for(int i=1;i<=n;i++)
{
memcpy(g,f,sizeof(f));
for(int j=v[i];j<=m;j++) g[j]-=g[j-v[i]],g[j]=(g[j]%10+10)%10;
for(int j=1;j<=m;j++) printf("%d",g[j]%10);
printf("\n");
}
}
t2(我把poj的跳了)
这个比较新颖,让我感觉到了背包不止可以做费用的问题
这方面来想背包性的dp就是对于两个渐进的状态的最优值的dp
比如这个题就是dp的联通性的问题
#include<bits/stdc++.h>
using namespace std;
int n,begin,maxlevel,ans;
int a[51],f[51][1001];
int main()
{
scanf("%d%d%d",&n,&begin,&maxlevel);
f[0][begin]=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=maxlevel;j>=0;j--)
{
if(j-a[i]>=0)
f[i][j]=f[i][j]||f[i-1][j-a[i]];
if(j+a[i]<=maxlevel)
f[i][j]=f[i][j]||f[i-1][j+a[i]];
}
}
for(int i=maxlevel;i>=1;i--) if(f[n][i]==1) {printf("%d",i);return 0;}
printf("-1");
return 0;
}
t3
这个还是比较有意思,首先可以看出询问和物品都可以离线的,只是这个\(b\)有一点难整
实际上这个可以直接当作我们要求的东西,我们以另一种眼光来看,背包实际上是一个状态路径的过程,他是将路径虚化了的图的遍历,既然如此我们的状态就可以看做点
那么我们实际只要求出我们可以从起始点到结束点的最优的方案,\(b\)也就迎刃而解
那就直接上代码吧
#include <cstdio>
#include <algorithm>
using namespace std;
struct th
{
int a,b,c;
}sth[1000010];
struct query
{
int m,k,s;
int id;
}q[1000010];
int n,m;
int f[1000010];
bool ans[1000010];
bool cmp1(th a,th b)
{
return a.a<b.a;
}
bool cmp2(query a,query b)
{
return a.m<b.m;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&sth[i].c,&sth[i].a,&sth[i].b);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&q[i].m,&q[i].k,&q[i].s);
q[i].id=i;
}
sort(sth+1,sth+n+1,cmp1);
sort(q+1,q+m+1,cmp2);
int j=1;
f[0]=1e9;
for(int i=1;i<=m;i++)
{
while(j<=n&&sth[j].a<=q[i].m)
{
for(int k=100000;k>=sth[j].c;k--)
{
f[k]=max(f[k],min(f[k-sth[j].c],sth[j].b));
}
j++;
}
if(f[q[i].k]>(q[i].m+q[i].s)) ans[q[i].id]=1;
}
for(int i=1;i<=m;i++)
{
if(ans[i]) printf("TAK\n");
else printf("NIE\n");
}
}