uva10400 Game Show Math(DP)
注意除以0和溢出的情况
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int dp[110][64000]; int a[110],n,x,k,ans[110]; int main(){ int t; cin>>t; while(t--){ cin>>n; for(int i=0;i<n;i++) cin>>a[i]; memset(dp,0,sizeof dp); cin>>x; dp[0][a[0]+32000]=1; for(int i=1;i<n;i++){ for(int j=-32000;j<=32000;j++){ for(int k=1;k<=4;k++){ if(k==1){ if(j+a[i]<-32000||j+a[i]>32000) continue; if(dp[i-1][j+32000]) dp[i][j+a[i]+32000]=k; }else if(k==2){ if(j-a[i]<-32000||j-a[i]>32000) continue; if(dp[i-1][j+32000]) dp[i][j-a[i]+32000]=k; }else if(k==3){ if(j*a[i]<-32000||j*a[i]>32000) continue; if(dp[i-1][j+32000]) dp[i][j*a[i]+32000]=k; }else{ if(a[i]==0) continue; if(j/a[i]<-32000||j/a[i]>32000) continue; if(j%a[i]!=0) continue; if(dp[i-1][j+32000]) dp[i][j/a[i]+32000]=k; } } } } if(dp[n-1][x+32000]){ k=0; int now=x; for(int i=n-2;i>=0;i--){ for(int j=1;j<=4;j++){ if(j==1){ if(dp[i][now-a[i+1]+32000]) {ans[i+1]=1;now-=a[i+1];break;} }else if(j==2){ if(dp[i][now+a[i+1]+32000]) {ans[i+1]=2;now+=a[i+1];break;} }else if(j==3){ if(a[i]==0) {ans[i]=j;now=a[i];break;} if(dp[i][now/a[i+1]+32000]) {ans[i+1]=3;now/=a[i+1];break;} }else{ if(dp[i][now*a[i+1]+32000]) {ans[i+1]=4;now*=a[i+1];break;} } } } cout<<a[0]; for(int i=1;i<n;i++){ if(ans[i]==1) cout<<"+"; else if(ans[i]==2) cout<<"-"; else if(ans[i]==3) cout<<"*"; else cout<<"/"; cout<<a[i]; } cout<<"="<<x; cout<<endl; }else{ cout<<"NO EXPRESSION"<<endl; } } return 0; }