Description

Rabbit成功地打开了大门后,没多久就见到了梦寐以求的宝藏。里面的宝石种类共有N 种,每一种都有一个体积v 和它的价值val 。(已知第i 种宝石的体积为i ,编号从1 ~N )更让Rabbit兴奋的是,每种宝石的数量还是无穷无尽的。
Rabbit当然想把所有宝石全都带回家,但是她带的袋子却最多只能装下总体积为V 的宝石,所以贪心的Rabbit决定要带走总体积恰好为V 的宝石。
现在她突然想知道自己在拿走宝石数量恰好为N 的情况下总价值最大为多少?

Input

输入数据第一行是一个正整数T ,表示数据组数。(T<=20 )
每组数据占两行。
第一行为两个整数N,V 。(0<N<=1000,N<=V<=min(N∗N,2∗N) )
接下来一行有N个整数,代表N种宝石的价值vali 。(0<vali<=10000 )

Output

每组测试数据输出一行,代表在满足拿走宝石总体积恰为V 和数量恰好为N 的情况下Rabbit能拿走宝石的最大总价值。

Sample Input

1

3 5

6 2 4

Sample Output

16

C++版本一

#include<queue>
#include<stack>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int dp[2001][2001];
int dis[2001][2001];
int w[2001];
int v[2001];
int main()
{
    int n,c,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&c);
        int i,j;
        memset(dp,0,sizeof(dp));
        memset(dis,0,sizeof(dis));
        for(i=1; i<=n; i++){
            scanf("%d",&w[i]);
            v[i]=i;
        }
        for(i=1; i<=n; i++){
            for(j=0; j<=c; j++){
                for(int k=0; k*v[i]<=j&&k<=n; k++)
                {
                    if(dis[i][j]+k<=n){
                        dp[i][j]=max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
                        dis[i][j]+=k;
                    }

                }
            }
        }
        printf("%d\n",dp[n][c]);
    }
    return 0;
}

C++版本二

#include<queue>
#include<stack>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int dp[2001];
int dis[2001];
int w[2001];
int v[2001];
int main()
{
    int n,c,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&c);
        int i,j;
        memset(dp,0,sizeof(dp));
        memset(dis,0,sizeof(dis));
        for(i=1; i<=n; i++){
            scanf("%d",&w[i]);
            v[i]=i;
        }
        for(i=1;i<=n;i++){
            for(j=v[i];j<=c;j++){
                if(dis[i]+1<=n){
                    dis[i]+=1;
                    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
                }
            }
        }
        printf("%d\n",dp[c]);
    }
    return 0;
}

 

以上都是错解

因为个数的限制我们数组再加一维

#include<queue>
#include<stack>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int dp[1010][2001];
int dis[2001];
int w[2001];
int v[2001];
int main()
{
    int n,c,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&c);
        int i,j;
        memset(dp,0,sizeof(dp));
        memset(dis,0,sizeof(dis));
        for(i=1; i<=n; i++){
            scanf("%d",&w[i]);
            v[i]=i;
        }
        for(i=1;i<=n;i++){
            for(j=v[i];j<=c;j++){
                if(dis[i]+1<=n){
                    dis[i]+=1;
                    dp[dis[i]][j]=max(dp[dis[i]-1][j],dp[dis[i]-1][j-v[i]]+w[i]);
                }
            }
        }
        printf("%d\n",dp[n][c]);
    }
    return 0;
}