UVa 12563 Jin Ge Qu hao dp:0-1リュックサック問題


UVA-12563
Jin Ge Jin Qu hao
Time Limit: 1000 MS
 
メモリLimit: アンロックnown
 
64 bit IO Format: %lld&%ll
Submit Status
(If you smile when you see the title,this problem is foryou^^
    For those who don't know KTV、see:http://en.wikipedia.org/wiki/Karaoke_ボックス
    The e is one very popur song caled Jin Ge Jin Qu()It is a mix of 37 songs,and is extremiely long(11 minutes and 18 seconds)—I know there there there Jin Ge Qu II,and some other unefiely long.provens
    Why is it popurSuppose you have only 15 seconnds left(until your time is up)、then You shou dselect another song song song son son son son son son son son son son song song song song song song song song sour possible、because the KTV not crudit cruble stop stop.it.com 105and if you select Jin Ge Jin Qu,you’ll get 663 extra seconds!
    Now that you still have some time,but you’d like to make a plan now.You shoud stick to the follwing rules:
    • Don’t sing a song more than onece.
    • For each song of length t,ether sing it for exactlyt seconds,or don’t sing it at all.
    • When a song is finished、always immediately start a new song.
    Your goal is simple:sing as many songs as possible、and leave KTV as late as possible(since we have rule 3、this also maxizes the total lengths of all song we sing)when there ties.
Input
    The firstオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンラインオンライン(1≦n≦50、1≦t≦10 9)、the number of caddddddddsisisisitesong song song ininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininin seconds.Each length will be less than 3 minutes—I know that most songs are longer than 3 minutes.But don't forget that we could manaualy“cut”the song after we satisfied、before the song want the andature“parth”
    It is garanted that the sum of lengths of all songs(including Jin Ge Jin Qu)will be strictly larger than t.
Output
    For each test case、print the maximumber of songs、and the total lengthsof song'll sing.
    Explanion:
    In the first example、the best we can do is to sing the third song(80 seconds)、then Jin Ge Jin Qu for another 678 seconds.
    In the second example,we sing the first two(30+69=99 seconds).The n we still have one secondleft,so we can sing Jin Ge Qu for extra 678 seconds.However,iwe we sing the first andandandandandand inininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininincan’t sing Jin Ge Qu anymore!
The question is from here
My Solution:
劉先生は私達に多くのデータをくれました。歌の総時間はn*18-1+678及び50*180-678=9677を超えません。
タイトルのt<=10^9ほど怖くないです。最大9677ですから、dp[n][t]ができます。最大の歌曲数を求めて、しかもこの前提の下で時間はできるだけ長いです。
//Your goal is simple:sing as many sors as possible、and leave KTV as late as possible(since we have rule 3、this also/maximizes the total lengths of all song we sing)when there are.ties.
タイトルのこの言葉は当時は理解していませんでした。時間が多くかかりました。d、dwを分けると時間が一番多くなるかもしれないので、曲数が一番多くないです。これでWAになります。
実はleave KTV as late as possible when there aresです。 if文を使って一緒に作ります。 
アルゴリズム:0-1リュックサック問題の方法は計画方向で読み取りながら計算します。 
#include <iostream>
#include <cstdio>
#include <cstring>
//#define LOCAL
using namespace std;

int d[52][40000],dw[52][40000];

int main()
{
    #ifdef LOCAL
    freopen("a.txt","r",stdin);
    #endif // LOCAL
    int T,n,t,w,ans, kase = 1;
    scanf("%d", &T);
    while(T--){
        ans = 0;
        scanf("%d%d", &n, &t);
        for(int i = 1; i <= n; i++){
            scanf("%d", &w);
            for(int j = t; j > 0; j--){
                d[i][j] = (i == 1 ? 0 : d[i-1][j]);
        /*            dp       
                if(j > w) d[i][j] = max(d[i][j], d[i-1][j-w]+1);

                dw[i][j] = (i == 1 ? 0 : dw[i-1][j]);
                if(j > w ) dw[i][j] = max(dw[i][j], dw[i-1][j-w]+w);
        */
                dw[i][j] = (i == 1 ? 0 : dw[i-1][j]);
                if(j > w){
                    int& a = d[i][j];
                    int& b = d[i-1][j-w];
                    if(a < b+1) {a = b+1; dw[i][j]=dw[i-1][j-w]+w;}
                    else if(a == b+1) dw[i][j] = max(dw[i][j],dw[i-1][j-w]+w);

                }
            }
        }
        //  max{d[n][i]}       
        for(int i = 1; i <= t; i++){
            if(d[n][i] > ans) ans = d[n][i];// time = i;}
        }
        //cout<<dw[n][t]<<endl;
        printf("Case %d: ",kase++);
        printf("%d %d
",ans+1,dw[n][t]+678); } return 0; }
ありがとうございます。