题意:有a、b、c三个人同时工作,三个人做不同的任务需要不同的时间,但最后要求三个人做事情的总时间相同,输出做完所有任务需要的最少时间,如果无法达到三个人总工作时间相同,则输出“No”
当时一股脑筋觉着是最大流或者其他图论的东西,然后也往dp上想过,就连状态表示都没想出来。后来借鉴了一下大牛们的做法,标准做法应该是bfs所有可能情况,然后再一一帅选。这个bfs好久没写过了,暂时就没写。
还有一种特别巧妙的方法:
#include#include #include #include using namespace std; #define maxn 250 //maxn设为250是保证250>=120*2 #define see(x) cout<<#x<<":"< < y){ x = y; } } int main(){ int n, a, b, c; int i, j, k, l; while(~scanf("%d",&n)){ memset(dp,-1,sizeof(dp)); dp[0][121][121] = 0; //把初始值设置在121处,是一个很巧的方法 //平时一般都喜欢吧初始值设置在0、1处,但是此题,有加有减,121是一个减去120后大于0,加上120后小于maxn的数 for(i=0;i =0){ //本来以为可以不用了,觉得反正有一个0,所以其他的-1 不用忽略也行 //后来发现如果不加的话会相当混乱,难以保证最后的结果是由以赋初值的dp[0][121][121]得来的,而且-1<0 有木有!!! if(j+a =0&&k+b =0){ adjust(dp[i+1][j][k-c],dp[i][j][k]+c); } } } } //see(dp[i+1][121][121]) } if(dp[n][121][121]==-1){ printf("NO\n"); } else{ printf("%d\n",dp[n][121][121]/3); } } return 0; }