原题: http://codeforces.com/gym/101848/problem/E
题意:
有2n个菜有各自的价格,每天会随机给出n个菜供选择。你现在有p元,每天可以先充钱再吃一次饭,或者不吃。问能否在365天内使余额为0。
解析:
首先是交互题的要求,每次输入后都要输出一条,并且输出完后要刷新缓冲区。(直接endl或者加fflush(stdout)),在余额为0后直接exit(0)结束程序。
首先是可以无限次充钱(100为单位),所以-25=75,所以状态只有0~99了(100可以特判掉)。可以用bfs来维护到达每个点需要最少几步。
当一个状态可以转移到一个步数较少的状态就直接转移。因为必定存在一个菜使得一个状态往更少的状态转移,且出现的概率至少1/2,所以不用担心365天后完不成。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[2009];
int dp[2009];
bool vis[2009];
int main(){
int n,p;
cin>>n>>p;
for(int i=1;i<=2*n;i++)cin>>a[i];
queue<int>Q;
vis[0]=1;
dp[0]=0;
Q.push(0);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=1;i<=2*n;i++){
int v=(u+a[i])%100;
if(vis[v])continue;
vis[v]=1;
dp[v]=dp[u]+1;
Q.push(v);
}
}
int res=p;
for(int ii=1;ii<=365;ii++){
int now[1009];
for(int i=1;i<=n;i++)scanf("%d",&now[i]);
if(res==100){
cout<<0<<' '<<now[1]<<endl;
res-=a[now[1]];
if(res==0)exit(0);
continue;
}
int have=0;
for(int i=1;i<=n;i++){
int to=(res-a[now[i]]+100)%100;
if(dp[to]<dp[res]){
int ans=0;
if(res-a[now[i]]<0)ans++;
cout<<ans<<' '<<now[i]<<endl;
have=1;
res=to;
i=n;
}
}
if(!have){
cout<<0<<' '<<0<<endl;
}
if(res==0)exit(0);
}
}