SRM512 Div1Easy MysteriousRestaurant

問題URL:MysteriousRestaurant
こういう実装>考察な問題を1発ACできるかどうかは結構大事な気がするし、そういう意味ではSRMらしい出題。

考察

サンプル1を見ると、1日だけいる場合と8日いる場合とでは、取る料理の種類が異なることがわかる。なので日を進めるたび、曜日(7n日前)の料理をおさらいして最小コストを再計算してやるとよさそう。

実装

7日目まではソートして一番左にくるやつを選ぶ。以降は曜日でかかったコストをいったんbudgetに戻してから再計算。この方法だと貪欲にやってる感が強いので見通しはいい。

#include <bits/stdc++.h>
using namespace std;
const int INF=1145141919;

class MysteriousRestaurant {
public:
    int calc(char c){
        int ret;
        if('0'<=c&&c<='9') ret=c-'0';
        if('A'<=c&&c<='Z') ret=c-'A'+10;
        if('a'<=c&&c<='z') ret=c-'a'+36;
        return ret;
    }
    int maxDays( vector <string> prices, int budget ){
        int day[7];
        int ret=0,n=prices.size(),m=prices[0].size();
        for(int i=0;i<n;i++){
            if(ret<7){
                string tmp=prices[i];
                sort(tmp.begin(),tmp.end());
                char c=tmp.front();
                int cost=calc(c);
                if(budget-cost>=0){
                    day[i]=cost;
                    budget-=cost;
                    ret++;
                }else{
                    return ret;
                }
            }else{
                budget+=day[i%7];
                int cost=INF;
                for(int j=0;j<m;j++){
                    int sum=0;
                    for(int k=i;k>=0;k-=7){
                        sum+=calc(prices[k][j]);
                    }
                    cost=min(cost,sum);
                }
                if(budget-cost>=0){
                    day[i%7]=cost;
                    budget-=cost;
                    ret++;
                }else{
                    return ret;
                }
            }
        }
        return ret;
    }
};