UESTC Pick The Sticks (背包变形)

来源:互联网 发布:配置windows卡在100% 编辑:程序博客网 时间:2024/05/18 03:36

该题是15年CCPC的D题,背包变形,昨天队内组队赛和队友搞了出来 。 各种超时,能优化的地方都搞了才勉强过,应该是姿势不太对。

与普通背包唯一的不同之处就是该题的木板可以超出桌面,只要重心在桌面上就行,那么最多只有两个木板超出桌面,那么不妨尽量多的超出(一半在桌子上),为其他木板留出更大的空间。  这样我们就必须增加一维,表示超出桌面的木板个数。  对于每个木板有两种决策:选还是不选。对于选的木板又有两种决策:是否放在边上让其一半超出桌面。

细节参见代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const double eps = 1e-6;const int INF = 1000000000;const int maxn = 1000 + 5;const int maxl = 2000 + 5;int T,n,m,kase=0;ll d[2][2*maxl][3],w[maxn],v[maxn],L;int main() {    scanf("%d",&T);    while(T--) {        scanf("%d%lld",&n,&L);        L *= 2;        ll ans = 0, u = 0;        for(int i=0;i<=L;i++)            for(int k=0;k<3;k++) d[0][i][k] = 0;        for(int i=1;i<=n;i++) {            scanf("%lld%lld",&w[i],&v[i]), w[i] *= 2;            ans = ans>v[i]?ans:v[i];            for(ll j=0;j<=L;j++) {                for(int k=0;k<=2;k++) {                    d[1-u][j][k] = d[u][j][k];                    if(k > 0 && j >= (w[i]>>1)) d[1-u][j][k] = (d[1-u][j][k]>d[u][j-(w[i]>>1)][k-1]+v[i])?d[1-u][j][k]:d[u][j-(w[i]>>1)][k-1]+v[i];                    if(j >= w[i]) d[1-u][j][k] = (d[1-u][j][k]> d[u][j-w[i]][k]+v[i])?d[1-u][j][k]: d[u][j-w[i]][k]+v[i];                }            }            u = 1-u;        }        ans = (d[u][L][0]>ans)?d[u][L][0]:ans;        ans = (d[u][L][1]>ans)?d[u][L][1]:ans;        ans = (d[u][L][2]>ans)?d[u][L][2]:ans;        printf("Case #%d: %lld\n",++kase,ans);    }    return 0;}


0 0
原创粉丝点击