UVA 242 - Stamps and Envelope Size

在一次编程过程中,用户遇到了翻译错误导致的问题,原本的题意与实际描述完全相反,使得输出结果出现错误。通过使用背包思想进行动态规划,最终成功解决此问题。

被刘汝佳的翻译简直坑懵比了。


题意说的正好和题目描述相反。 输出最短的说成最长的。最小的序列 说成 最大的。 我也是醉了。 WA了好多次。


利用背包的思想。 dp【i】【j】 来表示  总和为 i 的邮票 的数量 为 j


这样就很容易做出来了


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MAXN 100+10
#define INF 1<<30
#define mod 1000007
int a[MAXN][MAXN];
bool judge(int m,int n)
{
    if(a[m][0]!=a[n][0])
      return a[m][0]<a[n][0];
    int i=a[m][0];
    for(;i>=1;i--)
       if(a[m][i]!=a[n][i])
         return a[m][i]<a[n][i];
    return true;
}
int main (){
    int s;
    while(scanf("%d",&s) != EOF && s){
        int t;
        int co = 0;
        int zu = 0;
        scanf("%d",&t);
        memset(a,0,sizeof(a));
        for(int z = 1; z <= t; z++){
            int n;
            int sum[MAXN*MAXN][100] = {0}; // i 为和  j为 数量
            scanf("%d",&n);
            a[z][0] = n;
            for(int i = 1; i <= n; i++){
                int num;
                scanf("%d",&num);
                a[z][i] = num;
            }
            sum[0][0] = 1;
            for(int i = 0; i <= 1000; i++){  // 邮票总和
                for(int j = 0; j <= s; j++){ // 邮票个数
                    for(int k = 1; k <= n; k++){  // 所有邮票的值
                        if(sum[i][j] && i + a[z][k] <= 1000 && j+1 <= s){
                            sum[i+a[z][k]][j+1] ++;
                        }
                    }
                }
            }
            for(int i = 1; i <= 1000; i++){
                int flag = 0;
                for(int j = 1; j <= s; j++){
                    if(sum[i][j]){
                        flag = 1;
                    }
                }
                if(flag){
                    if(i > co){
                        co = i;
                        zu = z;
                    }
                    if(i == co){
                        if(a[z][0] < a[zu][0]){
                            zu = z;
                        }
                        else if(judge(z,zu))
                            zu = z;
                    }
                }
                else
                    break;
            }
        }
        printf("max coverage =%4d :",co);
        int len = a[zu][0];
        for(int i = 1; i <= len; i++){
                printf("%3d",a[zu][i]);
        }
        printf("\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值