N多校2018d3t1 PACM Team(多维背包+记录路径)

注意记录路径时path要五维,不能滚动数组,因为没有第几个物品来标明顺序的话,就可能在某个物品的dp中导致path 的两个状态对应同一个物品,导致wa或者超时!

还有dp数组可以用short int存储

ac代码:

#include<bits/stdc++.h>
using namespace std;
#define per(i,a,b) for(int i=a;i <= b;i++)
#define Max(a,b) a=max(a,b)
#define Min(a,b) a=min(a,b)
#define Sz(x) (int)x.size()
typedef long long ll;
ll gcd(ll a,ll b){while(b){ll t=b;b=a%b;a=t;} return a;}
const int inf=0x3f3f3f3f;
#define siz 37
int n,dp[siz][siz][siz][siz],p[siz],a[siz],c[siz],m[siz],g[siz],P,A,C,M;
bool path[siz][siz][siz][siz][siz];
set<int>st;
void init()
{
    st.clear();
    memset(dp,0,sizeof(dp));
    memset(path,false,sizeof(path));
}

int main()
{
    std::ios::sync_with_stdio(false);
    while(scanf("%d",&n)!=EOF){
        init();
        int px,ax,cx,mx;
        for(int i=0;i<n;i++){
            scanf("%d %d %d %d %d",&p[i],&a[i],&c[i],&m[i],&g[i]);
        }
        scanf("%d %d %d %d",&P,&A,&C,&M);
        per(pxx,p[0],P)per(axx,a[0],A)per(cxx,c[0],C)per(mxx,m[0],M){dp[pxx][axx][cxx][mxx]=g[0];path[0][pxx][axx][cxx][mxx]=true;}
        for(int i=1;i<n;i++){
            for(px=P;px>=p[i];px--){
                for(ax=A;ax>=a[i];ax--){
                    for(cx=C;cx>=c[i];cx--){
                        for(mx=M;mx>=m[i];mx--){
                            if(dp[px][ax][cx][mx]<(dp[px-p[i]][ax-a[i]][cx-c[i]][mx-m[i]]+g[i])){
                                dp[px][ax][cx][mx]=(dp[px-p[i]][ax-a[i]][cx-c[i]][mx-m[i]]+g[i]);
                                path[i][px][ax][cx][mx]=true;
                            }
                        }
                    }
                }
            }
        }
        px=P;ax=A;cx=C;mx=M;
        int tmp=n-1;
        /*while(path[tmp][px][ax][cx][mx]){
            px-=p[tmp];ax-=a[tmp];cx-=c[tmp];mx-=m[tmp];
            tmp=path[px][ax][cx][mx];
            if(tmp==-1)break;
            st.insert(tmp);

        }*/
        while(tmp>=0&&px>=0&&ax>=0&&cx>=0&&mx>=0){
            if(path[tmp][px][ax][cx][mx]){
                st.insert(tmp);
                px-=p[tmp];
                ax-=a[tmp];
                cx-=c[tmp];
                mx-=m[tmp];
            }
            tmp--;
        }
        printf("%d
",st.size());
        if(st.empty()==true)continue;
        set<int>::iterator it=st.begin();
        printf("%d",*it);
        it++;
        for(;it!=st.end();it++){
            printf(" %d",*it);
        }
        printf("
");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/WindFreedom/p/9373981.html