隐藏页面特效

POJ之01背包系列

poj3624 Charm Bracelet

模板题

没有要求填满,所以初始化为0就行

#include<cstdio> #include<iostream> using namespace std; #define N 15010 int n,m,v[N],c[N],f[N]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&c[i]); for(int i=1;i<=n;i++){ for(int j=m;j>=v[i];j--){ f[j]=max(f[j],f[j-v[i]]+c[i]); } } printf("%d\n",f[m]); return 0; }

 

poj3628 Bookshelf 2

 

#include<cstdio> #include<iostream> using namespace std; #define N 21000000 int n,m,sum,ans,c[25],f[N]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&c[i]),sum+=c[i]; for(int i=1;i<=n;i++){ for(int j=sum;j>=c[i];j--){ f[j]=max(f[j],f[j-c[i]]+c[i]); } } for(int i=1;i<=sum;i++){ if(f[i]>=m){ ans=f[i]-m;break; } } printf("%d\n",ans); return 0; }

 

 

 

 

poj1745 Divisibility

 

这道题如果取摸后范围比较小,第二维不大于100,然后记忆化背包(非递归搜索),根据能达到的值推能达到的值,衍生出前n个时的所有状态。

 

#include<cstdio> #include<iostream> using namespace std; #define N 10005 int n,k,c[N]; bool f[N][105]; int main(){ scanf("%d%d",&n,&k); for(int i=0,x;i<n;i++){ scanf("%d",&x); if(x<0) x=-x; c[i]=x%k; } f[0][c[0]]=1; for(int i=1;i<n;i++){ for(int j=0;j<k;j++){ if(f[i-1][j]){ f[i][(j+c[i])%k]=1; f[i][(j+k-c[i])%k]=1; } } } puts(f[n-1][0]?"Divisible":"Not divisible"); return 0; }

 

 

 

 

poj1976  A Mini Locomotive

 

3辆车运货,共有n堆货,每辆可以运连续k堆,求最大运货量

 

保证k*3<=n;也就是说要运货量最大必须堆数为k。

 

f[i][j]为前j次前i堆最大运货量的最大运货量

 

如果i<j*k;那么只能全运

 

第i堆不运:f[i-1][j]

 

第i堆运:f[i-k][j-1]+sum;

 

#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 50010 int n,k,T,s[N],f[N][4]; int main(){ scanf("%d",&T); while(T--){ memset(f,0,sizeof f); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i]+=s[i-1]; scanf("%d",&k); for(int i=1;i<=n;i++){ for(int j=1;j<=3;j++){ if(i<j*k) f[i][j]=i; else f[i][j]=max(f[i-1][j],f[i-k][j-1]+s[i]-s[i-k]); } } printf("%d\n",f[n][3]); } return 0; }

 

 

 

 

poj1837 Balance

 

状态压缩求方案数

注意要平移数组

 

#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define p 7500 #define N 21 int n,m,h[N],w[N],f[N][p*2+10]; int main(){ scanf("%d%d",&m,&n); for(int i=0;i<m;i++) scanf("%d",&h[i]); for(int i=1;i<=n;i++) scanf("%d",&w[i]); f[0][p]=1; for(int i=1;i<=n;i++){ for(int k=0;k<=p<<1;k++){ if(f[i-1][k]){ for(int j=0;j<m;j++){ f[i][k+h[j]*w[i]]+=f[i-1][k]; } } } } printf("%d\n",f[n][p]); return 0; }

 

 

 

poj1948  Triangular Pastures

 

n个线,组一个三角形,求三角形的最大面积。

 

海伦公式

 

  • formula,p为半周长

 

因为周长已知,知道两条边就能确定面积。

 

设f[i][j](i>j),然后确定每一条边是否加入那个边,由已知状态推出未知状态,随之更新最大面积。

 

每条边不可能超过周长的一半。

 

#include<cstdio> #include<cmath> #include<iostream> using namespace std; #define M 45 #define N 1605 int n,c,a[M]; bool f[N][N]; int ans=-0x7fffffff; int check(int x,int y){ double t1=x; double t2=y; double t3=c-x-y; if(t1+t2<t3||t1+t3<t2||t3+t2<t1) return -1.0; double t=c*1.0/2.0; double res=sqrt(t*(t-t1)*(t-t2)*(t-t3))*100.0; return res; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i),c+=a[i]; f[0][0]=1; for(int i=1;i<=n;i++){ for(int j=c>>1;j>=0;j--){ for(int k=c>>1;k>=j;k--){ if(j>=a[i]&&f[j-a[i]][k]) f[j][k]=1; if(k>=a[i]&&f[j][k-a[i]]) f[j][k]=1; if(f[j][k]) ans=max(ans,check(j,k)); } } } printf("%d\n",ans); return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/5781739.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(2001)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示